2

假设我有一个模型Warehouse、一个模型Car和一个模型Dealer

模型Car就像:

attr_accessible :make, :year
belongs_to :warehouse
belongs_to :dealer

控制器Cars就像:

def create
  car = current_dealer.find(params[:car][:warehouse_id]).cars.new(params[:car])
  car.save!
end

的观点Cars#new是这样的:

<%= semantic_form_for @car do |f| %>
  <%= f.inputs do %>
    <%= f.input :warehouse, :include_blank => false %>
    <%= f.input :make %>
    <%= f.input :year %>
  <% end %>
<% end %>

经销商加车时可以选择仓库,上面的代码是防止批量分配的(也就是经销商将汽车添加到他们不拥有的仓库),但是它引发了一个异常说:warehouse_id不能批量分配,那是因为它带有参数太像了params[:car][:warehouse_id]

如何在不手动分配属性的情况下摆脱该错误?无论如何,这是一个好方法吗?

PS我试过params[:car].delete(:warehouse_id),但这看起来不是正确的方法。

4

3 回答 3

2

由于 :warehouse_id 不是 car 的大量可分配属性,因此您不能从表单将其作为 car 的属性发布。如果您以这种方式命名参数,即使您在控制器中对它们不做任何操作,Rails 也会引发质量分配错误。

而不是做(非格式特定):

<%= f.hidden_field :warehouse_id %>

做:

<%= hidden_field_tag :warehouse_id, @car.warehouse_id %>

我对formtastic不太熟悉,但我认为上面的行应该有效。

在控制器中:

def create
  @car = current_dealer.find(params[:warehouse_id]).cars.new(params[:car])
  @warehouse = Warehouse.find(params[:warehouse_id])
  @car.warehouse = @warehouse
  @car.save!
end

这有点乏味,我知道。不幸的是,保护您的代码需要更多的努力。

结论params[:car][:warehouse_id]=批量分配

于 2012-07-01T19:47:38.523 回答
1

停止使用 attr_accessible,使用strong_parameters

消除attr_accessible :make, :year

添加gem 'strong_parameters'到您的 Gemfile。

添加include ActiveModel::ForbiddenAttributesProtection到您的每个模型中。

然后,替换:

car = current_dealer.find(params[:car][:warehouse_id]).cars.new(params[:car])

和:

car = current_dealer.find(params[:car][:warehouse_id]).cars.new(params.require(:car).permit([:make, :year]))
于 2012-08-18T06:37:45.330 回答
0

批量分配仅确定是否可以通过表单(或 API)设置字段,它不控制可以设置的内容。问题是您正在尝试使用质量分配来控制数据的验证或限制。在您的情况下,您希望能够warehouse_id通过用户选择的选择列表保存 a,因此它必须可用于批量分配以使用标准参数方法来创建汽车。

建议的解决方案是首先使用 Formtasticselect输入来限制经销商可能选择的值。虽然我不知道您目前如何限制仓库,但一般版本是:

f.input :warehouse, :as => :select, :collection => "Whatever your selection rule is"

这应该确保只有经销商可用的仓库列表实际显示在表格中。

这并不能解决具有足够技术知识的人可以更改 URL 中的warehouse_id 并仍然发布到他们不拥有的仓库的问题。因此,您还应该在 Car 模型上添加一个验证,以确保只有属于经销商的仓库才是有效的选择。

这应该可以解决您的问题,为您需要的仓库 ID 保留批量分配,同时仍确保经销商只能选择属于他们的仓库。

于 2012-07-02T13:50:54.470 回答