diff --git a/lib/her/model/http.rb b/lib/her/model/http.rb index 09ab84a3..9b7a86ee 100644 --- a/lib/her/model/http.rb +++ b/lib/her/model/http.rb @@ -68,10 +68,11 @@ def #{method}(path, params={}) path = build_request_path_from_string_or_symbol(path, params) params = to_params(params) unless #{method.to_sym.inspect} == :get send(:'#{method}_raw', path, params) do |parsed_data, response| - if parsed_data[:data].is_a?(Array) || active_model_serializers_format? || json_api_format? + + if parsed_data[:data].is_a?(Array) || json_api_format? || (active_model_serializers_format? && parsed_data[:data].has_key?(pluralized_parsed_root_element)) new_collection(parsed_data) else - new(parse(parsed_data[:data]).merge :_metadata => parsed_data[:metadata], :_errors => parsed_data[:errors]) + new_from_parsed_data(parsed_data) end end end diff --git a/spec/model/associations_spec.rb b/spec/model/associations_spec.rb index fc952721..2cbddc4d 100644 --- a/spec/model/associations_spec.rb +++ b/spec/model/associations_spec.rb @@ -279,6 +279,7 @@ builder.adapter :test do |stub| stub.get("/users/1") { |env| [200, {}, { :user => { :id => 1, :name => "Tobias Fünke", :comments => [{ :id => 2, :body => "Tobias, you blow hard!", :user_id => 1 }, { :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/2") { |env| [200, {}, { :user => { :id => 2, :name => "Lindsay Fünke", :organization_id => 1 } }.to_json] } + stub.get("/users/2/role") { |env| [200, {}, { :role => { :id => 3, :body => "User" } }.to_json] } stub.get("/users/1/comments") { |env| [200, {}, { :comments => [{ :id => 4, :body => "They're having a FIRESALE?" }] }.to_json] } stub.get("/users/2/comments") { |env| [200, {}, { :comments => [{ :id => 4, :body => "They're having a FIRESALE?" }, { :id => 5, :body => "Is this the tiny town from Footloose?" }] }.to_json] } stub.get("/users/2/comments/5") { |env| [200, {}, { :comment => { :id => 5, :body => "Is this the tiny town from Footloose?" } }.to_json] } @@ -288,6 +289,7 @@ spawn_model "Foo::User" do parse_root_in_json true, :format => :active_model_serializers has_many :comments, class_name: "Foo::Comment" + has_one :role, class_name: "Foo::Role" belongs_to :organization end spawn_model "Foo::Comment" do @@ -298,6 +300,10 @@ parse_root_in_json true, :format => :active_model_serializers end + spawn_model "Foo::Role" do + parse_root_in_json true, :format => :active_model_serializers + end + @user_with_included_data = Foo::User.find(1) @user_without_included_data = Foo::User.find(2) end @@ -309,6 +315,12 @@ @user_with_included_data.comments.first.body.should == "Tobias, you blow hard!" end + it "maps a hash of included data through has_one" do + @user_with_included_data.role.should be_a(Foo::Role) + @user_with_included_data.role.id.should == 1 + @user_with_included_data.role.body.should == "Admin" + end + it "does not refetch the parents models data if they have been fetched before" do @user_with_included_data.comments.first.user.object_id.should == @user_with_included_data.object_id end @@ -320,6 +332,12 @@ @user_without_included_data.comments.first.body.should == "They're having a FIRESALE?" end + it "fetches data that was not included through has_one" do + @user_without_included_data.role.should be_a(Foo::Role) + @user_without_included_data.role.id.should == 3 + @user_without_included_data.role.body.should == "User" + end + it "fetches has_many data even if it was included, only if called with parameters" do @user_with_included_data.comments.where(:foo_id => 1).length.should == 1 end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 415caf11..60a938f8 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -18,6 +18,9 @@ @spawned_models = [] end + config.filter_run :focus + config.run_all_when_everything_filtered = true + config.after :each do @spawned_models.each do |model| Object.instance_eval { remove_const model } if Object.const_defined?(model)