This is certainly not impossible, though you may have to switch up your parameter naming a bit.
When you pass the JSON above to the controller, it either gets passed as parameters to a constructor:
Session.new(params[:session])
Or gets passed to the #update_attributes method on a persisted Session instance:
@session = Session.find(params[:id])
@session.update_attributes(params[:session])
Both the constructor and #update_attributes methods turn parameters like "plan_id" into assigment method calls. That is,
@session.update_attributes(:plan_id => "1")
Turns into (inside the #update_attributes method):
@session.plan_id = "1"
So, this works for your plan_id and weight attributes, because you have both #plan_id= and #weight= setter methods. You also have an #exercise_sets= method given to you by has_many :exercise_sets
. However, the #exercise_sets= method expects ExerciseSet objects, not ExerciseSet attributes.
Rails is capable of doing what you are trying to do via the #accepts_nested_attributes_for class method. Try this:
class Session < ActiveRecord::Base
has_many :exercise_sets, :dependent => :destroy
has_many :exercises, :through => :exercise_sets
accepts_nested_attributes_for :exercise_sets
end
This sets up (metaprograms) an #exercise_sets_attributes= method for you. So just modify your JSON to:
{
"plan_id":3,
"weight":60,
"exercise_sets_attributes": [
{
"created_at":"2012-06-13T14:55:57Z",
"ended_at":"2012-06-13T14:55:57Z",
"weight":"80.0",
"repetitions":10,
"exercise_id":1
}
]
}
More info: http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html