假设我有一个模型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]
等参数。
如何在不手动分配属性的情况下摆脱该错误?反正这是个好方法吗?
P.S。我尝试过params[:car].delete(:warehouse_id)
,但这样做似乎不正确。
由于: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]
=质量分配
停止使用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])
with:
car = current_dealer.find(params[:car][:warehouse_id]).cars.new(params.require(:car).permit([:make, :year]))
质量分配仅确定是否可以通过表单(或API)设置字段,它不控制可以设置的内容。问题是您正在尝试使用批量分配来控制数据的验证或限制。在您的情况下,您希望能够通过用户选择的选择列表保存warehouse_id
,因此它必须可用于批量分配,才能使用标准参数方法创建汽车。
建议的解决方案是首先使用Formtastic select
输入来限制经销商可能选择的值。尽管我不知道您目前如何限制仓库,但通用版本是:
f.input :warehouse, :as => :select, :collection => "Whatever your selection rule is"
这应确保在表格中仅实际显示经销商可用的仓库清单。
这不能解决具有足够技术知识的人可以更改URL中的Warehouse_id并仍过帐到他们不拥有的仓库的问题。因此,您还应该在Car模型上添加验证,以确保只有属于经销商的仓库才是有效的选择。
这应该可以解决您的问题,将所需的Warehouse_id分配到位,同时仍确保经销商只能选择属于他们的仓库。
质量分配通常在模型绑定期间作为MVC的一部分发生。一个简单的例子是您在网站上有一个正在编辑一些数据的表单。您的模型上还具有一些属性,这些属性不能作为表单的一部分进行编辑,而是用于控制表单的显示,或者可能根本不使用。
这是为防止批量分配而为您提供的一些可用选项的快速总结。尽管您肯定会建议使用后一种2模型方法中的一种,但是哪种方法取决于您自己。还有其他选项,例如通过TryUpdateModelAsync <>进行显式绑定,但是我展示的选项代表了一些最常见的方法。无论您做什么,都不要盲目地绑定视图模型(如果您拥有不应由用户编辑的属性,否则您可能会感到讨厌)。
感谢您为我们共享批量分配信息。许多学生担心作业,但现在不用担心,因为locus assignments在这里为您服务。我们提供最佳的任务服务,例如AS和A级课程,理学硕士,本科课程,商务四级,基础课程,入门级课程,业务管理活动,文学学士和文学学士荣誉等。