From f76c5c88e350f2fec869bb29869ebdf3bcdc9ccd Mon Sep 17 00:00:00 2001 From: Denis Talakevich Date: Wed, 3 Oct 2018 11:23:19 +0300 Subject: [PATCH] #303 optional add default to changes --- lib/json_api_client/resource.rb | 16 ++++- test/unit/association_test.rb | 107 +++++++++++++++++++++++++++++++- 2 files changed, 119 insertions(+), 4 deletions(-) diff --git a/lib/json_api_client/resource.rb b/lib/json_api_client/resource.rb index 01748945..74793e1f 100644 --- a/lib/json_api_client/resource.rb +++ b/lib/json_api_client/resource.rb @@ -35,6 +35,8 @@ class Resource :request_params_class, :keep_request_params, instance_accessor: false + class_attribute :add_defaults_to_changes, + instance_writer: false self.primary_key = :id self.parser = Parsers::Parser self.paginator = Paginating::Paginator @@ -48,6 +50,7 @@ class Resource self.associations = [] self.request_params_class = RequestParams self.keep_request_params = false + self.add_defaults_to_changes = false #:underscored_key, :camelized_key, :dasherized_key, or custom self.json_key_format = :underscored_key @@ -314,9 +317,7 @@ def initialize(params = {}) self.relationships = self.class.relationship_linker.new(self.class, params.delete("relationships") || {}) self.attributes = self.class.default_attributes.merge(params) - self.class.schema.each_property do |property| - attributes[property.name] = property.default unless attributes.has_key?(property.name) || property.default.nil? - end + setup_default_properties self.class.associations.each do |association| if params.has_key?(association.attr_name.to_s) @@ -480,6 +481,15 @@ def reset_request_select!(*resource_types) protected + def setup_default_properties + self.class.schema.each_property do |property| + unless attributes.has_key?(property.name) || property.default.nil? + attribute_will_change!(property.name) if add_defaults_to_changes + attributes[property.name] = property.default + end + end + end + def method_missing(method, *args) association = association_for(method) diff --git a/test/unit/association_test.rb b/test/unit/association_test.rb index f31ece36..1fdd3833 100644 --- a/test/unit/association_test.rb +++ b/test/unit/association_test.rb @@ -46,12 +46,89 @@ class MultiWordParent < Formatted class MultiWordChild < Formatted belongs_to :multi_word_parent + self.read_only_attributes = read_only_attributes + [:multi_word_parent_id] + + def self.key_formatter + JsonApiClient::DasherizedKeyFormatter + end + + def self.route_formatter + JsonApiClient::UnderscoredKeyFormatter + end +end + +class Account < TestResource + property :name + property :is_active, default: true + property :balance +end + +class UserAccount < TestResource + self.add_defaults_to_changes = true + property :name + property :is_active, default: true + property :balance end class AssociationTest < MiniTest::Test + def test_default_properties_no_changes + stub_request(:post, 'http://example.com/accounts'). + with(headers: { content_type: 'application/vnd.api+json', accept: 'application/vnd.api+json' }, body: { + data: { + type: 'accounts', + attributes: { + name: 'foo' + } + } + }.to_json) + .to_return(headers: { content_type: 'application/vnd.api+json' }, body: { + data: { + id: '1', + type: 'accounts', + attributes: { + name: 'foo', + is_active: false, + balance: '0.0' + } + } + }.to_json) + record = Account.new(name: 'foo') + assert record.save + assert_equal(false, record.is_active) + assert_equal('0.0', record.balance) + end + + def test_default_properties_changes + stub_request(:post, 'http://example.com/user_accounts'). + with(headers: { content_type: 'application/vnd.api+json', accept: 'application/vnd.api+json' }, body: { + data: { + type: 'user_accounts', + attributes: { + name: 'foo', + is_active: true + } + } + }.to_json) + .to_return(headers: { content_type: 'application/vnd.api+json' }, body: { + data: { + id: '1', + type: 'user_accounts', + attributes: { + name: 'foo', + is_active: true, + balance: '0.0' + } + } + }.to_json) + record = UserAccount.new(name: 'foo') + assert record.save + assert_equal(true, record.is_active) + assert_equal('0.0', record.balance) + end + def test_belongs_to_urls_are_formatted - request = stub_request(:get, "http://example.com/multi-word-parents/1/multi-word-children") + request = stub_request(:get, "http://example.com/multi_word_parents/1/multi_word_children") .to_return(headers: {content_type: "application/vnd.api+json"}, body: { data: [] }.to_json) MultiWordChild.where(multi_word_parent_id: 1).to_a @@ -59,6 +136,34 @@ def test_belongs_to_urls_are_formatted assert_requested(request) end + def test_belongs_to_urls_create_record + stub_request(:post, 'http://example.com/multi_word_parents/1/multi_word_children'). + with(headers: { content_type: 'application/vnd.api+json', accept: 'application/vnd.api+json' }, body: { + data: { + type: 'multi_word_children', + attributes: { + foo: 'bar', + 'multi-word-field': true + } + } + }.to_json) + .to_return(headers: { content_type: 'application/vnd.api+json' }, body: { + data: { + id: '2', + type: 'multi_word_children', + attributes: { + foo: 'bar', + 'multi-word-field': true + } + } + }.to_json) + + record = MultiWordChild.new(multi_word_parent_id: 1, foo: 'bar', multi_word_field: true) + result = record.save + assert result + assert_equal('2', record.id) + end + def test_load_has_one stub_request(:get, "http://example.com/properties/1") .to_return(headers: {content_type: "application/vnd.api+json"}, body: {