如何防止以正确的方式对协会进行大规模分配?

问题描述 投票:2回答:4

假设我有一个模型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),但这样做似乎不正确。

ruby-on-rails mass-assignment
4个回答
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]=质量分配


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])

with:

car = current_dealer.find(params[:car][:warehouse_id]).cars.new(params.require(:car).permit([:make, :year]))

0
投票

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

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

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

这应确保在表格中仅实际显示经销商可用的仓库清单。

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

这应该可以解决您的问题,将所需的Warehouse_id分配到位,同时仍确保经销商只能选择属于他们的仓库。


0
投票

质量分配通常在模型绑定期间作为MVC的一部分发生。一个简单的例子是您在网站上有一个正在编辑一些数据的表单。您的模型上还具有一些属性,这些属性不能作为表单的一部分进行编辑,而是用于控制表单的显示,或者可能根本不使用。

这是为防止批量分配而为您提供的一些可用选项的快速总结。尽管您肯定会建议使用后一种2模型方法中的一种,但是哪种方法取决于您自己。还有其他选项,例如通过TryUpdateModelAsync <>进行显式绑定,但是我展示的选项代表了一些最常见的方法。无论您做什么,都不要盲目地绑定视图模型(如果您拥有不应由用户编辑的属性,否则您可能会感到讨厌)。

感谢您为我们共享批量分配信息。许多学生担心作业,但现在不用担心,因为locus assignments在这里为您服务。我们提供最佳的任务服务,例如AS和A级课程,理学硕士,本科课程,商务四级,基础课程,入门级课程,业务管理活动,文学学士和文学学士荣誉等。

© www.soinside.com 2019 - 2024. All rights reserved.