Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion lib/her/model/associations/association.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,21 @@ def fetch(opts = {})
return @opts[:default].try(:dup) if @parent.new?

path = build_association_path -> { "#{@parent.request_path(@params)}#{@opts[:path]}" }
@klass.get(path, @params).tap do |result|

# XXX: Depending on the case, we route through fetching a collection
# or a single resource (has_one/belongs_to)
request_association(path, @params).tap do |result|
@cached_result = result unless @params.any?
return result
end
end

# @private
def request_association(path, params)
if @opts[:default].is_a? Array
@klass.get_collection(path, @params)
else
@klass.get(path, @params)
end
end

Expand Down
7 changes: 6 additions & 1 deletion lib/her/model/attributes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -179,9 +179,14 @@ def instantiate_record(klass, parsed_data)
#
# @private
def instantiate_collection(klass, parsed_data = {})
records = klass.extract_array(parsed_data).map do |record|
raw_data = klass.extract_array(parsed_data)

# XXX: This method should always return a collection
raw_data = [] if raw_data.blank?
records = raw_data.map do |record|
instantiate_record(klass, data: record)
end

Her::Collection.new(records, parsed_data[:metadata], parsed_data[:errors])
end

Expand Down
12 changes: 12 additions & 0 deletions spec/model/associations_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,7 @@
before do
spawn_model "Foo::User" do
has_many :comments, class_name: "Foo::Comment"
has_many :feeds, class_name: "Foo::Feed"
has_one :role, class_name: "Foo::Role"
belongs_to :organization, class_name: "Foo::Organization"
has_many :posts, inverse_of: :admin
Expand All @@ -289,6 +290,10 @@
parse_root_in_json true
end

spawn_model "Foo::Feed" do
belongs_to :user
end

spawn_model "Foo::Post" do
belongs_to :admin, class_name: "Foo::User"
end
Expand All @@ -308,6 +313,7 @@
builder.adapter :test do |stub|
stub.get("/users/1") { [200, {}, { id: 1, name: "Tobias Fünke", comments: [{ comment: { id: 2, body: "Tobias, you blow hard!", user_id: 1 } }, { comment: { id: 3, body: "I wouldn't mind kissing that man between the cheeks, so to speak", user_id: 1 } }], role: { id: 1, body: "Admin" }, organization: { id: 1, name: "Bluth Company" }, organization_id: 1 }.to_json] }
stub.get("/users/1/comments") { [200, {}, [{ comment: { id: 4, body: "They're having a FIRESALE?" } }].to_json] }
stub.get("/users/1/feeds") { [204, {}, ''.to_json] }
stub.get("/users/1/role") { [200, {}, { id: 3, body: "User" }.to_json] }
stub.get("/users/1/posts") { [200, {}, [{ id: 1, body: "blogging stuff", admin_id: 1 }].to_json] }
stub.get("/organizations/1") { [200, {}, { organization: { id: 1, name: "Bluth Company Foo" } }.to_json] }
Expand All @@ -325,6 +331,12 @@
expect(user.comments.first.body).to eq("Tobias, you blow hard!")
end

it "when a has_many doesn't have anything" do
expect(user.feeds).to eq([])
expect(user.feeds.first).to eq(nil)
expect(user.feeds.length).to eq(0)
end

it "does not refetch the parents models data if they have been fetched before" do
expect(user.comments.first.user.object_id).to eq(user.object_id)
end
Expand Down