Rails 4 Strong Params has_many与JSON [英] Rails 4 Strong Params has_many with JSON
问题描述
我正在尝试将json传递给客户端,并让rails负责处理对象的创建.
I'm attempting to pass json up on the client side and have rails take care of handling the object creation.
这是我的模特:
class Order < ActiveRecord::Base
has_many :order_items, :autosave => true
belongs_to :menu_session
end
class OrderItem < ActiveRecord::Base
belongs_to :order
has_one :menu_item
end
控制器
class OrderController < ApplicationController
#POST /order/create
def create
@order = Order.new(order_params)
@order.save
end
private
def order_params
params.require(:order).permit(:comments, :menu_session_id, :order_items => [:menu_item_id])
end
end
json数据:
{'order': {'comments': 'none', 'menu_session_id': '9', 'order_items':[{'menu_item_id': '5'}, {'menu_item_id': '5'}]}};
javascript
The 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错误.但是,我已经花了一段时间研究它的变体,无法使其正常工作.官方文档似乎并不涉足这一领域,我在这里找到的每个示例都涉及表格.
Clearly, either my json is messed up or the ruby .permit is wrong. However, I've been playing with variations of this for a while now and cannot get it to work. The official documentation doesn't seem to venture into this, and every example I have found here deals with forms.
任何人都知道发生了什么事吗?我不能成为第一个尝试这种方法的人.
Anyone have any idea what is going on? I can't be the first to try this approach.
更新:
通过以下更改来解决此问题:
Worked around it by making the following changes:
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"]}
我认为这不是最好的方法,所以我暂时不回答这个问题,希望有一个最佳实践.
I don't think this would be the best way to do it, so I'm going to leave the question unanswered for now in hopes there is a best practice.
推荐答案
在这种情况下,不需要解决方法. ActiveRecord提供了一种直接通过params哈希创建子元素的自动方法.为此,请按照以下步骤操作:
The workaround is not necessary in this case. ActiveRecord provides an automagic way of creating child elements directly through the params hash. In order to accomplish this, follow the steps bellow:
-
在模型中配置嵌套属性
Configure Nested Attributes in the model
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
在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'}]}};
在您的控制器中,使 permit 接受您的新密钥
In your controller, make permit accept your new key
def order_params
params.require(:order).permit(:comments, :menu_session_id, :order_items_attributes => [:menu_item_id])
end
使用嵌套属性可以实现更多出色的功能.有关更多信息,请参见 Rails API上的ActiveRecord :: NestedAttributes
There is some more awesomeness possible to accomplish with Nested Attributes. For further information, see ActiveRecord::NestedAttributes at Rails API
这篇关于Rails 4 Strong Params has_many与JSON的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!