Rails 4 Strong Params has_many with JSON -
i'm attempting pass json on client side , have rails take care of handling object creation.
here models:
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
controller
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
the json data:
{'order': {'comments': 'none', 'menu_session_id': '9', 'order_items':[{'menu_item_id': '5'}, {'menu_item_id': '5'}]}};
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');
finally, error log:
started post "/order/create" 127.0.0.1 @ 2013-07-10 22:30:36 -0400 processing ordercontroller#create 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'
clearly, either json messed or ruby .permit wrong. however, i've been playing variations of while , cannot work. official documentation doesn't seem venture this, , every example have found here deals forms.
anyone have idea going on? can't first try approach.
update:
worked around making following changes:
class ordercontroller < applicationcontroller #post /order/create def create @order = order.new(order_params) order_items = order_item_params order_items.each |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 best way it, i'm going leave question unanswered in hopes there best practice.
the workaround not necessary in case. activerecord provides automagic way of creating child elements directly through params hash. in order accomplish this, follow steps bellow:
configure nested attributes in model
class order < activerecord::base # autosave enabled accepts_nested_attributes_for has_many :order_items belongs_to :menu_session accepts_nested_attributes_for :order_items end
include *_attributes key in json. in case, change order_items key order_items_attributes
{'order': {'comments': 'none', 'menu_session_id': '9', 'order_items_attributes':[{'menu_item_id': '5'}, {'menu_item_id': '5'}]}};
in controller, make permit accept new key
def order_params params.require(:order).permit(:comments, :menu_session_id, :order_items_attributes => [:menu_item_id]) end
there more awesomeness possible accomplish nested attributes. further information, see activerecord::nestedattributes @ rails api
Comments
Post a Comment