Skip to content

Commit

Permalink
Use nested path parameters from the parent when using build
Browse files Browse the repository at this point in the history
  • Loading branch information
chewi committed Feb 20, 2017
1 parent d1babba commit 4776753
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 6 deletions.
14 changes: 11 additions & 3 deletions lib/her/model/associations/has_many_association.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,18 @@ def self.parse(association, klass, data)
# user = User.find(1)
# new_comment = user.comments.build(:body => "Hello!")
# new_comment # => #<Comment user_id=1 body="Hello!">
# 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
Expand Down
12 changes: 11 additions & 1 deletion lib/her/model/associations/has_one_association.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,17 @@ def self.parse(*args)
# new_role = user.role.build(:title => "moderator")
# new_role # => #<Role user_id=1 title="moderator">
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
Expand Down
14 changes: 12 additions & 2 deletions spec/model/associations_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,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
Expand All @@ -502,6 +508,10 @@ def present?
expect(@comment.body).to eq("Hello!")
expect(@comment.user_id).to eq(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
Expand All @@ -511,7 +521,7 @@ def present?
builder.use Faraday::Request::UrlEncoded
builder.adapter :test do |stub|
stub.get("/users/10") { [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

Expand Down

0 comments on commit 4776753

Please sign in to comment.