Skip to content

Commit f1f03a1

Browse files
committed
Use nested path parameters from the parent when using build
1 parent ba68395 commit f1f03a1

File tree

3 files changed

+34
-6
lines changed

3 files changed

+34
-6
lines changed

lib/her/model/associations/has_many_association.rb

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,18 @@ def self.parse(association, klass, data)
4949
# user = User.find(1)
5050
# new_comment = user.comments.build(:body => "Hello!")
5151
# new_comment # => #<Comment user_id=1 body="Hello!">
52-
# TODO: This only merges the id of the parents, handle the case
53-
# where this is more deeply nested
5452
def build(attributes = {})
55-
@klass.build(attributes.merge(:"#{@parent.singularized_resource_name}_id" => @parent.id))
53+
@klass.build(attributes.merge(:"#{@parent.singularized_resource_name}_id" => @parent.id)).tap do |resource|
54+
begin
55+
resource.request_path
56+
rescue Her::Errors::PathError => e
57+
e.missing_parameters.each do |m|
58+
if id = @parent.get_attribute(m) || @parent.get_attribute("_#{m}")
59+
resource.send("#{m}=", id)
60+
end
61+
end
62+
end
63+
end
5664
end
5765

5866
# Create a new object, save it and add it to the associated collection

lib/her/model/associations/has_one_association.rb

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,17 @@ def self.parse(*args)
4545
# new_role = user.role.build(:title => "moderator")
4646
# new_role # => #<Role user_id=1 title="moderator">
4747
def build(attributes = {})
48-
@klass.build(attributes.merge(:"#{@parent.singularized_resource_name}_id" => @parent.id))
48+
@klass.build(attributes.merge(:"#{@parent.singularized_resource_name}_id" => @parent.id)).tap do |resource|
49+
begin
50+
resource.request_path
51+
rescue Her::Errors::PathError => e
52+
e.missing_parameters.each do |m|
53+
if id = @parent.get_attribute(m) || @parent.get_attribute("_#{m}")
54+
resource.send("#{m}=", id)
55+
end
56+
end
57+
end
58+
end
4959
end
5060

5161
# Create a new object, save it and associate it to the parent

spec/model/associations_spec.rb

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,13 @@ def present?
361361

362362
context "building and creating association data" do
363363
before do
364-
spawn_model "Foo::Comment"
364+
spawn_model "Foo::Like" do
365+
collection_path "/users/:user_id/comments/:comment_id/likes"
366+
end
367+
spawn_model "Foo::Comment" do
368+
collection_path "/users/:user_id/comments"
369+
has_many :likes
370+
end
365371
spawn_model "Foo::User" do
366372
has_many :comments
367373
end
@@ -373,6 +379,10 @@ def present?
373379
@comment.body.should == "Hello!"
374380
@comment.user_id.should == 10
375381
end
382+
it "uses nested path parameters from the parent" do
383+
@like = Foo::User.new(:id => 10).comments.build(:id => 20).likes.build
384+
@like.request_path.should == "/users/10/comments/20/likes"
385+
end
376386
end
377387

378388
context "with #create" do
@@ -382,7 +392,7 @@ def present?
382392
builder.use Faraday::Request::UrlEncoded
383393
builder.adapter :test do |stub|
384394
stub.get("/users/10") { |env| [200, {}, { :id => 10 }.to_json] }
385-
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] }
395+
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] }
386396
end
387397
end
388398

0 commit comments

Comments
 (0)