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:

  1. 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 
  2. 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'}]}}; 
  3. 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

Popular posts from this blog

javascript - Count length of each class -

What design pattern is this code in Javascript? -

hadoop - Restrict secondarynamenode to be installed and run on any other node in the cluster -