2013-10-04 58 views
3

我是新来的铁轨和在此基础上未经许可参数4

http://railscasts.com/episodes/403-dynamic-forms

,但我有在其他字段中存储数据的问题...... 我有一些建具有多个ProductField对象的ProductType对象。 ProductField对象也属于ProductType,Product对象属于ProductType。

因此,可以通过构造函数ProductType轻松地添加新的动态字段,但是当我尝试通过产品控制器在此字段中设置数据时,什么都不会发生。

我相信这个问题与使用强参数有关,但修复描述herehere没有帮助。

product.rb

class Product < ActiveRecord::Base 
    belongs_to :product_type 
    serialize :properties, Hash 
end 

product_type.rb

class ProductType < ActiveRecord::Base 
    has_many :fields, class_name: "ProductField" 
    accepts_nested_attributes_for :fields, allow_destroy: true 
end 

product_field.rb

class ProductField < ActiveRecord::Base 
    belongs_to :product_type 
end 

products_controller.rb

class ProductsController < ApplicationController 
    def new 
    @product = Product.new(product_type_id: params[:product_type_id]) 
    end 
    def product_params 
    params.require(:product).permit(:name, :price, :product_type_id, {:properties => []}) 
    end 

product_type_controller.rb

class ProductTypesController < ApplicationController 
    def product_type_params 
    params.require(:product_type).permit(:name, fields_attributes: [:id, :name, :field_type, :required, :product_type_id]) 
    end 

在控制台日志: 不允许的参数:性能

Started PATCH "/products/4" for 127.0.0.1 at 2013-10-04 22:54:59 +0400 
Processing by ProductsController#update as HTML 
Parameters: {"utf8"=>"✓", "authenticity_token"=>"my3ra60OUXexmmguk2eqRetizx3tWPMq04Z2PnODJMQ=", "product"=>{"product_type_id"=>"1", "name"=>"Product1", "properties"=>{"gjfghjf"=>"123", "123"=>[""]}, "price"=>"10"}, "commit"=>"Update Product", "id"=>"4"} 
Product Load (0.3ms) SELECT "products".* FROM "products" WHERE "products"."id" = ? LIMIT 1 [["id", "4"]] 
Unpermitted parameters: properties 

PS:也许有人看的时候遇到了类似的问题播客?

+0

你可以发布你的表单代码吗?我看到你在返回参数中得到了这个:'“properties”=> {“gjfghjf”=>“123”,“123”=> [“”]}。属性以两个项目的散列形式出现,其中一个是数组。在您的product_params中,它期望基于写入方式的允许标量值数组。 Railscast最初是使用Rails 4完成的吗? – Beartech

+0

如果你想测试它是如何在表单代码或'permit'语句中构造参数的问题,你可以这样做:'params.require(:product).permit!'。它会将所有内容列入白名单。适合测试,但对安全性非常不利,所以您需要在某个时刻对其进行分类。 – Beartech

+0

Yeap,params.require(:product).permit!真的在工作,但这对安全非常不利,你很对.. – AntonyZ

回答

12

如果要将嵌套散列作为参数返回,则必须在permit中命名数组中的键。

class ProductsController < ApplicationController 
def new 
@product = Product.new(product_type_id: params[:product_type_id]) 
end 
def product_params 
params.require(:product).permit(:name, :price, :product_type_id, {:properties => [:foo, :bar, :id]}) 
end 

如果你是动态生成的密钥,并且无法代码放到permit声明,那么你需要使用这种样式:

def product_params 
    params.require(:product).permit(:name, :price, :product_type_id).tap do |whitelisted| 
    whitelisted[:properties] = params[:product][:properties] 
    end 
end 

这不是一个新的用户最友好的代码,我刚刚完成了UW的3门课程证书课程,他们甚至从未涉足过.tap

这不是我的工作,我仍然只是像这样理解.permit的更深层部分。这是我使用的博客条目:Strong Parameters by Example

+0

非常感谢!完美的作品! – AntonyZ

+0

所以上面的代码没有任何修改工作?如果需要任何mod,请在这里留下评论,我会改变它,所以答案更准确。如果开箱即用,完美无瑕!我有点运气,因为我只是从我所了解的Strong Params和我读过的内容中推断出来的。 – Beartech