7

我目前有一个制造车辆的表格。车辆模型最初如下所示:

class Vehicle < ActiveRecord::Base
  attr_accessible :trim_id

  belongs_to :trim
end

您会注意到没有make_idmodel_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'} %>

但是,正如预期的那样,这会导致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

您会注意到我在这里尝试排除“日期”(也尝试过:日期) - 这是为了使用非嵌套属性进行测试。

但是,我发现该日期仍在提交中 - 任何人都可以使用 Hash#except 协助完成完整的控制器操作吗?

编辑 2:我已将 Beerlington 的答案标记为正确,因为它回答了原始问题 - 我在这里提出了一个后续问题:在生成 mass_assignment 错误之前使用 Hash#exclude 排除控制器操作中的嵌套表单字段?

4

1 回答 1

12

您可以使用Hash#except删除不需要的键:

@vehicle.update_attributes(params[:vehicle].except(:make, :model))
于 2012-08-31T12:01:40.237 回答