Rails 4 Strong Params has_many with JSON

我试图在客户端传递json并让rails负责处理对象创建。

这是我的模特:

class Order  true belongs_to :menu_session end class OrderItem < ActiveRecord::Base belongs_to :order has_one :menu_item end 

调节器

 class OrderController  [:menu_item_id]) end end 

json数据:

 {'order': {'comments': 'none', 'menu_session_id': '9', 'order_items':[{'menu_item_id': '5'}, {'menu_item_id': '5'}]}}; 

这个javascript

 var data = {}; data.order = {'comments': 'none', 'menu_session_id': '9', 'order_items':[{'menu_item_id': '5'}, {'menu_item_id': '5'}]}; $.post('http://localhost:3000/order/create', orders, function(){}, 'json'); 

最后,错误日志:

 Started POST "/order/create" for 127.0.0.1 at 2013-07-10 22:30:36 -0400 Processing by OrderController#create as JSON Parameters: {"order"=>{"comments"=>"none", "menu_session_id"=>"9", "order_items"=>{"0"=>{"menu_item_id"=>"5"}, "1"=>{"menu_item_id"=>"5"}}}} Completed 500 Internal Server Error in 52ms ActiveRecord::AssociationTypeMismatch (OrderItem(#28109220) expected, got Array(#16050620)): app/controllers/order_controller.rb:5:in `create' 

显然,要么我的json搞砸了,要么ruby .permit错了。 但是,我现在已经玩了一段时间的变化,并且无法让它发挥作用。 官方文档似乎没有涉及到这一点,我在这里找到的每个例子都涉及表单。

任何人都知道发生了什么事吗? 我不能成为第一个尝试这种方法的人。


更新:

通过进行以下更改来解决此问题:

 class OrderController < ApplicationController #POST /order/create def create @order = Order.new(order_params) order_items = order_item_params order_items.each do |item| @order.order_items << OrderItem.new(menu_item_id: item) end @order.save end private def order_params params.require(:order).permit(:comments, :menu_session_id) end def order_item_params params.require(:order_items) end end 

json: {"order":{"comments":"none","menu_session_id":"9"},"order_items":["5","5"]}

我不认为这是最好的方法,所以我现在要留下未回答的问题,希望有一个最好的做法。

在这种情况下,解决方法不是必需的。 ActiveRecord提供了一种通过params哈希直接创建子元素的自动方式。 为了实现此目的,请按照以下步骤操作:

  1. 在模型中配置嵌套属性

     class Order < ActiveRecord::Base # autosave is already enabled with accepts_nested_attributes_for has_many :order_items belongs_to :menu_session accepts_nested_attributes_for :order_items end 
  2. 在JSON中包含* _attributes键。 在您的情况下,将order_items键更改为order_items_attributes

     {'order': {'comments': 'none', 'menu_session_id': '9', 'order_items_attributes':[{'menu_item_id': '5'}, {'menu_item_id': '5'}]}}; 
  3. 在您的控制器中, 允许许可接受您的新密钥

     def order_params params.require(:order).permit(:comments, :menu_session_id, :order_items_attributes => [:menu_item_id]) end 

使用嵌套属性可以实现更多function。 有关更多信息,请参阅Rails API中的ActiveRecord :: NestedAttributes