我目前有一个制作车辆的表格。车型最初看起来像:
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'} %>
正如您将注意到的,make和model选择没有表单参数,因此被忽略。这样工作正常,车辆保存正确。
当我想编辑这种车辆时出现困难;因为make和model只是虚拟选择链接到修剪,它们最初设置为默认值,而不是正在编辑的车辆的品牌和型号。结果我将模型更新为:
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'} %>
但是,正如预期的那样,这导致Can't mass-assign protected attributes: 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#来协助完整的控制器操作吗?
编辑2:我已将Beerlington的答案标记为正确,因为它回答了原始问题 - 我在此处提出了一个后续问题:Excluding nested form fields in controller action with Hash#exclude before mass_assignment error is generated?
答案 0 :(得分:12)
您可以使用Hash#except删除不需要的密钥:
@vehicle.update_attributes(params[:vehicle].except(:make, :model))