diff --git a/lib/her/model/parse.rb b/lib/her/model/parse.rb index db43d98f..e31c746f 100644 --- a/lib/her/model/parse.rb +++ b/lib/her/model/parse.rb @@ -56,14 +56,23 @@ def to_params(attributes, changes={}) # @private # TODO: Handle has_one def embeded_params(attributes) - associations[:has_many].select { |a| attributes.include?(a[:data_key])}.compact.inject({}) do |hash, association| - params = attributes[association[:data_key]].map(&:to_params) - next if params.empty? - if association[:class_name].constantize.include_root_in_json? - root = association[:class_name].constantize.root_element - hash[association[:data_key]] = params.map { |n| n[root] } + (associations[:has_many] + associations[:has_one]).select { |a| attributes.include?(a[:data_key])}.compact.inject({}) do |hash, association| + # avoid hash is nil + hash ||= {} + params = {} + if attributes[association[:data_key]].respond_to?(:map) + params = attributes[association[:data_key]].map(&:to_params) else - hash[association[:data_key]] = params + params = attributes[association[:data_key]].to_params + end + # avoid nil in inject when params.empty? + if params.present? + if association[:class_name].constantize.include_root_in_json? + root = association[:class_name].constantize.root_element + hash[association[:data_key]] = params.map { |n| n[root] } + else + hash[association[:data_key]] = params + end end hash end diff --git a/spec/model/associations_spec.rb b/spec/model/associations_spec.rb index a3bf3f68..c862da08 100644 --- a/spec/model/associations_spec.rb +++ b/spec/model/associations_spec.rb @@ -112,7 +112,7 @@ spawn_model "Foo::User" do has_many :comments, class_name: "Foo::Comment" - has_one :role + has_one :role, class_name: "Foo::Role" belongs_to :organization has_many :posts, :inverse_of => :admin end diff --git a/spec/model/parse_spec.rb b/spec/model/parse_spec.rb index 4ef1bc32..deac9aae 100644 --- a/spec/model/parse_spec.rb +++ b/spec/model/parse_spec.rb @@ -342,4 +342,85 @@ def to_params expect(user.to_params).to eql(:user => {:first_name => 'Someone'}) end end + + context "two has_many relations" do + before do + Her::API.setup :url => "https://api.example.com" do |builder| + builder.use Her::Middleware::FirstLevelParseJSON + builder.use Faraday::Request::UrlEncoded + end + + Her::API.default_api.connection.adapter :test do |stub| + stub.get("/users/1") { |env| [200, {}, { :id => 1, :first_name => "Gooby", :last_name => "Pls", :posts=>[], :comments => [{ :id => 4, :body => "They're having a FIRESALE?" }] }.to_json] } + end + + spawn_model "Foo::User" do + has_many :posts, class_name:"Foo::Post" + has_many :comments, class_name:"Foo::Comment" + attributes :id, :first_name, :last_name + end + spawn_model "Foo::Post" do + attributes :body + end + spawn_model "Foo::Comment" do + attributes :id, :body + end + end + + it "get user json with comments and blank post" do + user = Foo::User.find(1) + expect(user.to_params).to eq({ :id => 1, :first_name => "Gooby", :last_name => "Pls", :posts=>[], :comments => [{ :id => 4, :body => "They're having a FIRESALE?" }] }) + end + end + + context "one has_many relation" do + before do + Her::API.setup :url => "https://api.example.com" do |builder| + builder.use Her::Middleware::FirstLevelParseJSON + builder.use Faraday::Request::UrlEncoded + end + + Her::API.default_api.connection.adapter :test do |stub| + stub.get("/users/1") { |env| [200, {}, { :id => 1, :first_name => "Gooby", :last_name => "Pls", :comments => [] }.to_json] } + end + + spawn_model "Foo::User" do + has_many :comments, class_name:"Foo::Comment" + attributes :id, :first_name, :last_name + end + spawn_model "Foo::Comment" do + attributes :id, :body + end + end + + it "get user json with blank comments" do + user = Foo::User.find(1) + expect(user.to_params).to eq({ :id => 1, :first_name => "Gooby", :last_name => "Pls", :comments => [] }) + end + end + context "one has_one relation" do + before do + Her::API.setup :url => "https://api.example.com" do |builder| + builder.use Her::Middleware::FirstLevelParseJSON + builder.use Faraday::Request::UrlEncoded + end + + Her::API.default_api.connection.adapter :test do |stub| + stub.get("/users/1") { |env| [200, {}, { :id => 1, :first_name => "Gooby", :last_name => "Pls", :role => {:id => 1, :name => "Admin"} }.to_json] } + end + + spawn_model "Foo::User" do + has_one :role, class_name:"Foo::Role" + attributes :id, :first_name, :last_name + end + spawn_model "Foo::Role" do + attributes :id, :name + end + end + + it "get user json with admin role" do + user = Foo::User.find(1) + expect(user.to_params).to eq({ :id => 1, :first_name => "Gooby", :last_name => "Pls", :role => {:id => 1, :name => "Admin"} }) + end + end end