我正在使用rails中的验证,例如:
validates_presence_of :some_field
我注意到如果验证失败,所有更改都会被数据库中的现有值覆盖。这是有道理的,因为页面基本上被重新加载(因为我从我的开发日志中收集),然而这增加了用户错误/挫折的风险,因为在一个字段中的单个错误将需要不幸的家伙重新进入他对所有领域所做的改变。
我的问题:如果验证失败,我怎样才能重新加载提交的数据?这样,用户可以纠正错误,而无需重新输入其他修订版本。
感谢您的任何建议。
修改 我的更新方法按要求如下:
def update
@incorporation = Incorporation.find(params[:id])
@company = @incorporation.company
begin
@company.name="#{params[:company][:names_attributes].values.first["name_string"]} #{params[:company][:names_attributes].values.first["suffix"]}"
rescue NoMethodError
@company.name="Company #{@company.id} (Untitled)"
end
if @company.update(company_params)
redirect_to incorporations_index_path
else
redirect_to edit_incorporation_path(@incorporation)
end
end
关于我的控制器的完整信息披露:上述update
来自我的incorporations_controller
,即使我正在更新我的Company
模型。 Company has_one :incorporation
。我这样做是因为,在我的应用程序的更大范围内,它使我的关联更清洁。
答案 0 :(得分:2)
将您的控制器更新为此
def update
@incorporation = Incorporation.find(params[:id])
@company = @incorporation.company
begin
@company.name="#{params[:company][:names_attributes].values.first["name_string"]} #{params[:company][:names_attributes].values.first["suffix"]}"
rescue NoMethodError
@company.name="Company #{@company.id} (Untitled)"
end
respond_to do |format|
if @company.update(company_params)
format.html { redirect_to({:action => "index"})}
else
format.html{render :edit}
format.json { render json: @incorporation.errors, status: :unprocessable_entity }
end
end
end
答案 1 :(得分:1)
要添加正确的答案,您可以清理一下代码:
def update
@incorporation = Incorporation.find params[:id]
respond_to do |format|
if @incorporation.update company_params
format.html { redirect_to({:action => "index"})}
else
format.html { render :edit }
format.json { render json: @incorporation.errors, status: :unprocessable_entity }
end
end
end
如果你正在使用accepts_nested_attributes_for
,你肯定应该不破解前端的关联对象。
您应该查找fat model, skinny controller
(让模型完成工作):
#app/models/company.rb
class Company < ActiveRecord::Base
before_update :set_name
attr_accessor :name_string, :name_suffix
private
def set_name
if name_string && name_suffix
self[:name] = "#{name_string} #{name_suffix}"
else
self[:name] = "Company #{id} (Untitled)"
end
end
end
这将允许您填充`公司的name
。直接编辑嵌套/关联对象是antipattern;一个黑客,后来会回来困扰你。
答案的关键是:render :edit
渲染编辑视图意味着您可以维护当前的@company
/ @incorporation
数据。
重定向将调用controller
的新实例,覆盖@incorporation
,因此您在前端看到的内容。