简体   繁体   English

如何用params hash获取数据?

[英]How to get data in params hash?

I have a Car model and an Brand model (each of which has_and_belongs_to_many). 我有一个汽车模型和一个品牌模型(每个模型都有_and_belongs_to_many)。 I am trying to create a new brand for a car. 我正在努力为汽车创造一个新的品牌。 The car model accepts nested attributes for brand. 汽车模型接受品牌的嵌套属性。

When I try 当我尝试

@car = Car.find(params[:car_id])
@brand = @car.brands.build(params[:brand])

I get a mass assignment error: 我收到了一个质量分配错误:

Can't mass-assign protected attributes: brands

Brands Controller: 品牌控制器:

class BrandsController < ApplicationController
 def create
  debugger
  @car = Car.find(params[:car_id])
  @brand= @car.brands.build(params[:brand])
  if @brand.save
   redirect_to @car
  else
   #do something
  end
 end 
end

Calling the debugger with 用调用调用器

pp params

Shows: 显示:

"brand"=>{"brands"=>{"name"=>"BMW"}},
"commit"=>"Create Brand",
"action"=>"create",
"controller"=>"brands",
"car_id"=>"4"}

The view looks like this: 该视图如下所示:

<%= form_for([@car, @car.brands.build]) do |f| %>
    <div class="field">
        <%= f.fields_for :brands do |a| %>
            <%= a.text_field :name, placeholder: "New Brand" %>
        <% end %>
    </div>
    <p><%= f.submit %></p>
<% end %>

I want the application to be secure so I want to set the brand attributes individually as opposed to passing the whole "brand" hash (which incidentally does not work). 我希望应用程序是安全的,所以我想单独设置品牌属性,而不是传递整个“品牌”哈希(顺便说一句不起作用)。 How can I get the brand name? 我怎样才能获得品牌名称? Something like 就像是

params[:brands].name?

Edit: 编辑:

I can get the brand name with 'params[:brand][:brands][:name]'. 我可以用'params [:brand] [:brands] [:name]'获得品牌名称。 Now it turns out that the brands table does not have a car_id since it is connected to a car with a join table. 现在事实证明,品牌表没有car_id,因为它连接到带有连接表的汽车。

<%= form_for @car do |f| %>
  <div class="field">
    <%= f.fields_for :brands do |a| %>
        <%= a.text_field :name, placeholder: "New Brand" %>
    <% end %>
  </div>
<p><%= f.submit %></p>
<% end %>

In your model: 在你的模型中:

class Car < ActiveRecord::Base
  has_many :brands
  accepts_nested_attributes_for :brands
  attr_accessible :brand_attributes
end

Although having a model accept attributes for another is a useful tool in some cases, it often tends to be cumbersome and violates single responsibility principal not only at the model level, but also at the controller and view layer. 虽然在某些情况下让模型接受另一个模型是一个有用的工具,但它往往很麻烦,并且不仅在模型级别而且在控制器和视图层违反单一责任主体。 Ultimately making it more difficult to refactor should your design need to change. 如果您的设计需要改变,最终会使重构变得更加困难。

Keeping with the philosophy of REST, instead of creating Brands through Cars, use a BrandsController to handle the lifecycle of a Brand. 遵循REST的理念,而不是通过汽车创建品牌,使用BrandsController来处理品牌的生命周期。

As for your requirement of security, setting a model's attributes manually does not provide any more security then passing the whole params hash assuming you are properly using attr_accessible. 至于您的安全性要求,手动设置模型的属性并不提供任何更多的安全性,因为假设您正确使用attr_accessible,则传递整个params哈希。 Giving it a whitelist of acceptable paramaters will tell the AR interface that everything else should be denied. 给它一个可接受的参数的白名单会告诉AR界面其他一切都应该被拒绝。

class Brand < ActiveRecord::Base
  attr_accessible :name
end

So if a brand belongs to a car, and someone tried to change the relationship by hacking a car_id into the form it would reject car_id from the hash, possibly even raising an exception depending on your settings. 因此,如果一个品牌属于汽车,并且有人试图通过将car_id黑客入侵到表单来改变关系,那么它会拒绝来自哈希的car_id,甚至可能根据您的设置提出异常。

config.active_record.mass_assignment_sanitizer = :strict

That will cause a ActiveModel::MassAssignmentSecurity::Error instead of just the Warning that is output into the logs. 这将导致ActiveModel::MassAssignmentSecurity::Error而不仅仅是输出到日志中的Warning。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM