我目前有一个构建车辆的表单。车辆模型最初如下所示:
class Vehicle < ActiveRecord::Base
attr_accessible :trim_id
belongs_to :trim
end
您会注意到没有 make_id
或 model_id
列;这些不是必需的,因为装饰属于模型,模型属于品牌,因此不需要将它们存储在车辆模型中。
问题出现在车辆形式上 - 我有一些链接的选择,我可以在其中选择品牌,然后选择模型,然后选择装饰。当我创建一辆新车时,以下代码可以正常工作:
<%= select("", "", Make.all.collect {|p| [ p.value, p.id ] }, {:prompt => 'Select Make'}, {} %>
<%= f.select("", "", options_for_select([]), {:prompt => 'Select Model'}, {} %>
<%= f.select(:trim_id, options_for_select([]), {:prompt => 'Select Trim'} %>
正如您将注意到的,选择的品牌和型号没有表单参数,因此会被忽略。这工作正常,并且车辆已正确保存。
当我想要编辑这辆车时,困难就出现了;因为品牌和型号只是虚拟选择链接到装饰,所以它们最初设置为默认值,而不是正在编辑的车辆的品牌和型号。结果我更新了我的模型,如下所示:
class Vehicle < ActiveRecord::Base
attr_accessible :trim_id
belongs_to :trim
has_one :model, :through => :trim
has_one :make, :through => :model
end
并将表单更新为:
<%= f.select(:make, Make.all.collect {|p| [ p.value, p.id ] }, {:prompt => 'Select Make'}, {} %>
<%= f.select(:model, options_for_select([]), {:prompt => 'Select Model'}, {} %>
<%= f.select(:trim_id, options_for_select([]), {:prompt => 'Select Trim'} %>
但是,正如预期的那样,这会导致无法批量分配 protected 属性:make、model
,因为 make 和 model 不可 attr_accessible (并且在任何情况下 make 和 model 列不存在)。
我的问题是:有没有办法在提交新车辆表单时忽略这些字段,但在编辑车辆时仍然让他们选择正确的值?
谢谢!
编辑:根据 Beerlington 的回答,我已更新我的 create
操作,如下所示:
def create
@sale = Sale.new
current_ability.attributes_for(:new, Sale).each do |key, value|
@sale.send("#{key}=", value)
end
@sale.update_attributes(params[:sale].except("date"))
authorize! :create, @sale
if @sale.save
redirect_to @sale, :notice => "Successfully created sale."
else
render :action => 'new'
end
end
您会注意到,我试图在此处排除“date”(也尝试过:date) - 这是为了使用非嵌套属性进行测试。
但是,我发现该日期仍在提交 - 任何人都可以使用 Hash# except 协助完成完整的 Controller 操作吗?
编辑2:我已将Beerlington的答案标记为正确,因为它回答了原始问题 - 我在这里提出了一个后续问题:Excluding nested form fields in controller action with Hash#exclude before mass_assignment error is generated?
最佳答案
您可以使用 Hash#except 删除不需要的 key :
@vehicle.update_attributes(params[:vehicle].except(:make, :model))
关于ruby-on-rails - 提交表单时忽略字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12214626/