diff --git a/lib/her/model/associations/has_many_association.rb b/lib/her/model/associations/has_many_association.rb index 63cef796..ade0d5b6 100644 --- a/lib/her/model/associations/has_many_association.rb +++ b/lib/her/model/associations/has_many_association.rb @@ -49,10 +49,18 @@ def self.parse(association, klass, data) # user = User.find(1) # new_comment = user.comments.build(:body => "Hello!") # new_comment # => # - # TODO: This only merges the id of the parents, handle the case - # where this is more deeply nested def build(attributes = {}) - @klass.build(attributes.merge(:"#{@parent.singularized_resource_name}_id" => @parent.id)) + @klass.build(attributes.merge(:"#{@parent.singularized_resource_name}_id" => @parent.id)).tap do |resource| + begin + resource.request_path + rescue Her::Errors::PathError => e + e.missing_parameters.each do |m| + if id = @parent.get_attribute(m) || @parent.get_attribute("_#{m}") + resource.send("_#{m}=", id) + end + end + end + end end # Create a new object, save it and add it to the associated collection diff --git a/lib/her/model/associations/has_one_association.rb b/lib/her/model/associations/has_one_association.rb index 80cb3cd3..a56c50dd 100644 --- a/lib/her/model/associations/has_one_association.rb +++ b/lib/her/model/associations/has_one_association.rb @@ -45,7 +45,17 @@ def self.parse(*args) # new_role = user.role.build(:title => "moderator") # new_role # => # def build(attributes = {}) - @klass.build(attributes.merge(:"#{@parent.singularized_resource_name}_id" => @parent.id)) + @klass.build(attributes.merge(:"#{@parent.singularized_resource_name}_id" => @parent.id)).tap do |resource| + begin + resource.request_path + rescue Her::Errors::PathError => e + e.missing_parameters.each do |m| + if id = @parent.get_attribute(m) || @parent.get_attribute("_#{m}") + resource.send("_#{m}=", id) + end + end + end + end end # Create a new object, save it and associate it to the parent diff --git a/spec/model/associations_spec.rb b/spec/model/associations_spec.rb index fc952721..4b47ff14 100644 --- a/spec/model/associations_spec.rb +++ b/spec/model/associations_spec.rb @@ -449,7 +449,13 @@ def present? context "building and creating association data" do before do - spawn_model "Foo::Comment" + spawn_model "Foo::Like" do + collection_path "/users/:user_id/comments/:comment_id/likes" + end + spawn_model "Foo::Comment" do + collection_path "/users/:user_id/comments" + has_many :likes + end spawn_model "Foo::User" do has_many :comments end @@ -461,6 +467,10 @@ def present? @comment.body.should == "Hello!" @comment.user_id.should == 10 end + it "uses nested path parameters from the parent" do + @like = Foo::User.new(:id => 10).comments.build(:id => 20).likes.build + @like.request_path.should == "/users/10/comments/20/likes" + end end context "with #create" do @@ -470,7 +480,7 @@ def present? builder.use Faraday::Request::UrlEncoded builder.adapter :test do |stub| stub.get("/users/10") { |env| [200, {}, { :id => 10 }.to_json] } - stub.post("/comments") { |env| [200, {}, { :id => 1, :body => Faraday::Utils.parse_query(env[:body])['body'], :user_id => Faraday::Utils.parse_query(env[:body])['user_id'].to_i }.to_json] } + stub.post("/users/10/comments") { |env| [200, {}, { :id => 1, :body => Faraday::Utils.parse_query(env[:body])['body'], :user_id => Faraday::Utils.parse_query(env[:body])['user_id'].to_i }.to_json] } end end