Class: JsonApiClient::Resource
- Inherits:
-
Object
- Object
- JsonApiClient::Resource
- Extended by:
- ActiveModel::Naming, ActiveModel::Translation, Forwardable
- Includes:
- ActiveModel::Conversion, ActiveModel::Serialization, ActiveModel::Validations, Helpers::Associatable, Helpers::Dirty, Helpers::DynamicAttributes
- Defined in:
- lib/json_api_client/resource.rb
Instance Attribute Summary collapse
-
#last_result_set ⇒ Object
Returns the value of attribute last_result_set.
-
#links ⇒ Object
Returns the value of attribute links.
-
#relationships ⇒ Object
Returns the value of attribute relationships.
-
#request_params ⇒ Object
Returns the value of attribute request_params.
Class Method Summary collapse
-
.connection(rebuild = false, &block) ⇒ Connection
Return/build a connection object.
-
.create(attributes = {}) ⇒ Resource
Create a new instance of this resource class.
- .create!(attributes = {}) ⇒ Object
-
.custom_headers ⇒ Hash
The current custom headers to send with any request made by this resource class.
-
.default_attributes ⇒ Hash
Default attributes that every instance of this resource should be initialized with.
-
.immutable(flag = true) ⇒ Boolean
Indicates whether this resource is mutable or immutable; by default, all resources are mutable.
- .inherited(subclass) ⇒ Object
- .key_formatter ⇒ Object
-
.load(params) ⇒ Resource
Load a resource object from attributes and consider it persisted.
-
.path(params = nil) ⇒ Object
Return the path or path pattern for this resource.
-
.prefix_params ⇒ Array
Param names that will be considered path params.
-
.requestor ⇒ Requestor
Returns the requestor for this resource class.
- .resolve_custom_type(type_name, class_name) ⇒ Object
-
.resource_name ⇒ String
The name of a single resource.
-
.resource_path ⇒ String
Specifies the relative path that should be used for this resource; by default, this is inferred from the resource class name.
- .route_formatter ⇒ Object
-
.schema ⇒ Schema
Returns the schema for this resource class.
-
.table_name ⇒ String
The table name for this resource.
-
.type ⇒ String
Specifies the JSON API resource type.
-
.with_headers(headers) ⇒ Object
Within the given block, add these headers to all requests made by the resource class.
Instance Method Summary collapse
- #as_json ⇒ Object
-
#as_json_api ⇒ Hash
When we represent this resource for serialization (create/update), we do so with this implementation.
-
#as_relation ⇒ Hash
When we represent this resource as a relationship, we do so with id & type.
-
#destroy ⇒ Boolean
Try to destroy this resource.
-
#destroyed? ⇒ Boolean
Whether or not this record has been destroyed to the database previously.
-
#initialize(params = {}) ⇒ Resource
constructor
Instantiate a new resource object.
- #inspect ⇒ Object
-
#mark_as_destroyed! ⇒ Object
Mark the record as destroyed.
-
#mark_as_persisted! ⇒ Object
Mark the record as persisted.
-
#new_record? ⇒ Boolean
Returns true if this is a new record (never persisted to the database).
- #path_attributes ⇒ Object
-
#persisted? ⇒ Boolean
Whether or not this record has been persisted to the database previously.
- #request_includes(*includes) ⇒ Object
- #request_select(*fields) ⇒ Object
- #reset_request_includes! ⇒ Object
- #reset_request_select!(*resource_types) ⇒ Object
-
#save ⇒ Boolean
Commit the current changes to the resource to the remote server.
-
#set_all_dirty! ⇒ Object
Mark all attributes for this record as dirty.
-
#update(attrs = {}) ⇒ Boolean
Alias to update_attributes.
- #update!(attrs = {}) ⇒ Object
-
#update_attributes(attrs = {}) ⇒ Boolean
Set the current attributes and try to save them.
- #update_attributes!(attrs = {}) ⇒ Object
- #valid?(context = nil) ⇒ Boolean
Methods included from Helpers::Associatable
#_belongs_to_params, #_cached_associations, #_cached_relationship, #_clear_belongs_to_params, #_clear_cached_relationship, #_clear_cached_relationships
Methods included from Helpers::Dirty
#attribute_change, #attribute_changed?, #attribute_was, #attribute_will_change!, #changed, #changed?, #changed_attributes, #clear_changes_information, #forget_change!, #set_all_attributes_dirty, #set_attribute_was
Methods included from Helpers::DynamicAttributes
#[], #[]=, #attributes, #attributes=
Constructor Details
#initialize(params = {}) ⇒ Resource
Instantiate a new resource object
370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 |
# File 'lib/json_api_client/resource.rb', line 370 def initialize(params = {}) params = params.with_indifferent_access @persisted = nil @destroyed = nil self.links = self.class.linker.new(params.delete(:links) || {}) self.relationships = self.class.relationship_linker.new(self.class, params.delete(:relationships) || {}) self.attributes = self.class.default_attributes.merge params.except(*self.class.prefix_params) self.forget_change!(:type) self.__belongs_to_params = params.slice(*self.class.prefix_params) setup_default_properties self.class.associations.each do |association| if params.has_key?(association.attr_name.to_s) set_attribute(association.attr_name, params[association.attr_name.to_s]) end end self.request_params = self.class.request_params_class.new(self.class) end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *args) ⇒ Object (protected)
615 616 617 618 619 620 621 |
# File 'lib/json_api_client/resource.rb', line 615 def method_missing(method, *args) relationship_definition = relationship_definition_for(method) return super unless relationship_definition relationship_data_for(method, relationship_definition) end |
Instance Attribute Details
#last_result_set ⇒ Object
Returns the value of attribute last_result_set.
17 18 19 |
# File 'lib/json_api_client/resource.rb', line 17 def last_result_set @last_result_set end |
#links ⇒ Object
Returns the value of attribute links.
17 18 19 |
# File 'lib/json_api_client/resource.rb', line 17 def links @links end |
#relationships ⇒ Object
Returns the value of attribute relationships.
17 18 19 |
# File 'lib/json_api_client/resource.rb', line 17 def relationships @relationships end |
#request_params ⇒ Object
Returns the value of attribute request_params.
17 18 19 |
# File 'lib/json_api_client/resource.rb', line 17 def request_params @request_params end |
Class Method Details
.connection(rebuild = false, &block) ⇒ Connection
Return/build a connection object
137 138 139 140 |
# File 'lib/json_api_client/resource.rb', line 137 def connection(rebuild = false, &block) _build_connection(rebuild, &block) connection_object end |
.create(attributes = {}) ⇒ Resource
Create a new instance of this resource class
169 170 171 172 173 |
# File 'lib/json_api_client/resource.rb', line 169 def create(attributes = {}) new(attributes).tap do |resource| resource.save end end |
.create!(attributes = {}) ⇒ Object
175 176 177 178 179 |
# File 'lib/json_api_client/resource.rb', line 175 def create!(attributes = {}) new(attributes).tap do |resource| raise(Errors::RecordNotSaved.new("Failed to save the record", resource)) unless resource.save end end |
.custom_headers ⇒ Hash
The current custom headers to send with any request made by this resource class
198 199 200 201 202 |
# File 'lib/json_api_client/resource.rb', line 198 def custom_headers return _header_store.to_h if superclass == Object superclass.custom_headers.merge(_header_store.to_h) end |
.default_attributes ⇒ Hash
Default attributes that every instance of this resource should be initialized with. Optionally, override this method in a subclass.
215 216 217 |
# File 'lib/json_api_client/resource.rb', line 215 def default_attributes {type: type} end |
.immutable(flag = true) ⇒ Boolean
Indicates whether this resource is mutable or immutable; by default, all resources are mutable.
106 107 108 |
# File 'lib/json_api_client/resource.rb', line 106 def immutable(flag = true) self._immutable = flag end |
.inherited(subclass) ⇒ Object
110 111 112 113 |
# File 'lib/json_api_client/resource.rb', line 110 def inherited(subclass) subclass._immutable = false super end |
.key_formatter ⇒ Object
226 227 228 |
# File 'lib/json_api_client/resource.rb', line 226 def key_formatter JsonApiClient::Formatter.formatter_for(json_key_format) end |
.load(params) ⇒ Resource
Load a resource object from attributes and consider it persisted
126 127 128 129 130 131 132 |
# File 'lib/json_api_client/resource.rb', line 126 def load(params) new(params).tap do |resource| resource.mark_as_persisted! resource.clear_changes_information resource.relationships.clear_changes_information end end |
.path(params = nil) ⇒ Object
Return the path or path pattern for this resource
151 152 153 154 155 156 157 158 159 160 161 162 163 |
# File 'lib/json_api_client/resource.rb', line 151 def path(params = nil) parts = [resource_path] if params && _prefix_path.present? path_params = params.delete(:path) || params parts.unshift(_set_prefix_path(path_params.symbolize_keys)) else parts.unshift(_prefix_path) end parts.reject!(&:blank?) File.join(*parts) rescue KeyError raise ArgumentError, "Not all prefix parameters specified" end |
.prefix_params ⇒ Array
Param names that will be considered path params. They will be used to build the resource path rather than treated as attributes
146 147 148 |
# File 'lib/json_api_client/resource.rb', line 146 def prefix_params _belongs_to_associations.map(&:param) end |
.requestor ⇒ Requestor
Returns the requestor for this resource class
207 208 209 |
# File 'lib/json_api_client/resource.rb', line 207 def requestor @requestor ||= requestor_class.new(self) end |
.resolve_custom_type(type_name, class_name) ⇒ Object
75 76 77 78 |
# File 'lib/json_api_client/resource.rb', line 75 def resolve_custom_type(type_name, class_name) classified_type = key_formatter.unformat(type_name.to_s).singularize.classify self.custom_type_to_class = custom_type_to_class.merge(classified_type => class_name.to_s) end |
.resource_name ⇒ String
The name of a single resource. i.e. Article -> article, Person -> person
90 91 92 |
# File 'lib/json_api_client/resource.rb', line 90 def resource_name name.demodulize.underscore end |
.resource_path ⇒ String
Specifies the relative path that should be used for this resource; by default, this is inferred from the resource class name.
119 120 121 |
# File 'lib/json_api_client/resource.rb', line 119 def resource_path table_name end |
.route_formatter ⇒ Object
230 231 232 |
# File 'lib/json_api_client/resource.rb', line 230 def route_formatter JsonApiClient::Formatter.formatter_for(route_format) end |
.schema ⇒ Schema
Returns the schema for this resource class
222 223 224 |
# File 'lib/json_api_client/resource.rb', line 222 def schema @schema ||= Schema.new end |
.table_name ⇒ String
The table name for this resource. i.e. Article -> articles, Person -> people
83 84 85 |
# File 'lib/json_api_client/resource.rb', line 83 def table_name route_formatter.format(resource_name.pluralize) end |
.type ⇒ String
Specifies the JSON API resource type. By default this is inferred from the resource class name.
98 99 100 |
# File 'lib/json_api_client/resource.rb', line 98 def type table_name end |
.with_headers(headers) ⇒ Object
Within the given block, add these headers to all requests made by the resource class
186 187 188 189 190 191 192 |
# File 'lib/json_api_client/resource.rb', line 186 def with_headers(headers) previous_headers = self.custom_headers self._custom_headers = headers yield ensure self._custom_headers = previous_headers end |
Instance Method Details
#as_json ⇒ Object
467 468 469 470 471 472 473 474 |
# File 'lib/json_api_client/resource.rb', line 467 def as_json(*) attributes.slice(self.class.primary_key, :type).tap do |h| relationships.as_json.tap do |r| h[:relationships] = r unless r.empty? end h[:attributes] = attributes.except(self.class.primary_key, :type).as_json end end |
#as_json_api ⇒ Hash
When we represent this resource for serialization (create/update), we do so with this implementation
458 459 460 461 462 463 464 465 |
# File 'lib/json_api_client/resource.rb', line 458 def as_json_api(*) attributes.slice(self.class.primary_key, :type).tap do |h| relationships_for_serialization.tap do |r| h[:relationships] = self.class.key_formatter.format_keys(r) unless r.empty? end h[:attributes] = self.class.key_formatter.format_keys(attributes_for_serialization) end end |
#as_relation ⇒ Hash
When we represent this resource as a relationship, we do so with id & type
450 451 452 |
# File 'lib/json_api_client/resource.rb', line 450 def as_relation attributes.slice(:type, self.class.primary_key) end |
#destroy ⇒ Boolean
Try to destroy this resource
525 526 527 528 529 530 531 532 533 534 535 536 537 538 |
# File 'lib/json_api_client/resource.rb', line 525 def destroy raise JsonApiClient::Errors::ResourceImmutableError if _immutable self.last_result_set = self.class.requestor.destroy(self) if last_result_set.has_errors? fill_errors false else mark_as_destroyed! _clear_cached_relationships _clear_belongs_to_params true end end |
#destroyed? ⇒ Boolean
Whether or not this record has been destroyed to the database previously
436 437 438 |
# File 'lib/json_api_client/resource.rb', line 436 def destroyed? !!@destroyed end |
#inspect ⇒ Object
540 541 542 |
# File 'lib/json_api_client/resource.rb', line 540 def inspect "#<#{self.class.name}:@attributes=#{attributes.inspect}>" end |
#mark_as_destroyed! ⇒ Object
Mark the record as destroyed
429 430 431 |
# File 'lib/json_api_client/resource.rb', line 429 def mark_as_destroyed! @destroyed = true end |
#mark_as_persisted! ⇒ Object
Mark the record as persisted
417 418 419 |
# File 'lib/json_api_client/resource.rb', line 417 def mark_as_persisted! @persisted = true end |
#new_record? ⇒ Boolean
Returns true if this is a new record (never persisted to the database)
443 444 445 |
# File 'lib/json_api_client/resource.rb', line 443 def new_record? !persisted? && !destroyed? end |
#path_attributes ⇒ Object
569 570 571 |
# File 'lib/json_api_client/resource.rb', line 569 def path_attributes _belongs_to_params.merge attributes.slice( self.class.primary_key ).with_indifferent_access end |
#persisted? ⇒ Boolean
Whether or not this record has been persisted to the database previously
424 425 426 |
# File 'lib/json_api_client/resource.rb', line 424 def persisted? !!@persisted && !destroyed? && has_attribute?(self.class.primary_key) end |
#request_includes(*includes) ⇒ Object
544 545 546 547 |
# File 'lib/json_api_client/resource.rb', line 544 def request_includes(*includes) self.request_params.add_includes(includes) self end |
#request_select(*fields) ⇒ Object
554 555 556 557 558 559 560 561 |
# File 'lib/json_api_client/resource.rb', line 554 def request_select(*fields) fields_by_type = fields. fields_by_type[type.to_sym] = fields if fields.any? fields_by_type.each do |field_type, field_names| self.request_params.set_fields(field_type, field_names) end self end |
#reset_request_includes! ⇒ Object
549 550 551 552 |
# File 'lib/json_api_client/resource.rb', line 549 def reset_request_includes! self.request_params.reset_includes! self end |
#reset_request_select!(*resource_types) ⇒ Object
563 564 565 566 567 |
# File 'lib/json_api_client/resource.rb', line 563 def reset_request_select!(*resource_types) resource_types = self.request_params.field_types if resource_types.empty? resource_types.each { |resource_type| self.request_params.remove_fields(resource_type) } self end |
#save ⇒ Boolean
Commit the current changes to the resource to the remote server. If the resource was previously loaded from the server, we will try to update the record. Otherwise if it's a new record, then we will try to create it
493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 |
# File 'lib/json_api_client/resource.rb', line 493 def save return false unless valid? raise JsonApiClient::Errors::ResourceImmutableError if _immutable self.last_result_set = if persisted? self.class.requestor.update(self) else self.class.requestor.create(self) end if last_result_set.has_errors? fill_errors false else self.errors.clear if self.errors self.request_params.clear unless self.class.keep_request_params mark_as_persisted! if updated = last_result_set.first self.attributes = updated.attributes self.links.attributes = updated.links.attributes self.relationships.attributes = updated.relationships.attributes clear_changes_information self.relationships.clear_changes_information _clear_cached_relationships end true end end |
#set_all_dirty! ⇒ Object
Mark all attributes for this record as dirty
477 478 479 480 |
# File 'lib/json_api_client/resource.rb', line 477 def set_all_dirty! set_all_attributes_dirty relationships.set_all_attributes_dirty if relationships end |
#update(attrs = {}) ⇒ Boolean
Alias to update_attributes
408 409 410 |
# File 'lib/json_api_client/resource.rb', line 408 def update(attrs = {}) update_attributes(attrs) end |
#update!(attrs = {}) ⇒ Object
412 413 414 |
# File 'lib/json_api_client/resource.rb', line 412 def update!(attrs = {}) update_attributes!(attrs) end |
#update_attributes(attrs = {}) ⇒ Boolean
Set the current attributes and try to save them
394 395 396 397 |
# File 'lib/json_api_client/resource.rb', line 394 def update_attributes(attrs = {}) self.attributes = attrs save end |
#update_attributes!(attrs = {}) ⇒ Object
399 400 401 402 |
# File 'lib/json_api_client/resource.rb', line 399 def update_attributes!(attrs = {}) self.attributes = attrs save ? true : raise(Errors::RecordNotSaved.new("Failed to update the record", self)) end |
#valid?(context = nil) ⇒ Boolean
482 483 484 485 |
# File 'lib/json_api_client/resource.rb', line 482 def valid?(context = nil) context ||= (new_record? ? :create : :update) super(context) end |