Class: JSONAPI::Consumer::Resource
- Inherits:
-
Object
- Object
- JSONAPI::Consumer::Resource
- Extended by:
- ActiveModel::Naming, ActiveModel::Translation, Forwardable
- Includes:
- ActiveModel::Conversion, ActiveModel::Serialization, ActiveModel::Validations, Associations::BelongsTo, Associations::HasMany, Associations::HasOne, Helpers::Dirty, Helpers::DynamicAttributes
- Defined in:
- lib/jsonapi/consumer/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.
Class Method Summary collapse
-
.authorize_with(jwt, &block) ⇒ Object
Run a command wrapped in an Authorization header.
-
.authorize_with=(jwt) ⇒ Object
Set the Authorization header to a JWT value.
-
.authorized? ⇒ Boolean
Returns based on the presence of an Authorization header.
-
.authorized_as ⇒ String
The Authorization header.
-
.clear_authorization! ⇒ Object
Clears the Authorization header.
-
.connection(rebuild = false, &block) ⇒ Connection
Return/build a connection object.
-
.create(attributes = {}) ⇒ Resource
Create a new instance of this resource class.
-
.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.
- .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.
-
.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.
-
#initialize(params = {}) ⇒ Resource
constructor
Instantiate a new resource object.
- #inspect ⇒ Object
-
#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).
-
#persisted? ⇒ Boolean
Whether or not this record has been persisted to the database previously.
-
#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_attributes(attrs = {}) ⇒ Boolean
Set the current attributes and try to save them.
- #valid?(context = nil) ⇒ Boolean
Methods included from Helpers::Dirty
#attribute_change, #attribute_changed?, #attribute_was, #attribute_will_change!, #changed, #changed?, #changed_attributes, #clear_changes_information, #set_all_attributes_dirty, #set_attribute_was
Methods included from Helpers::DynamicAttributes
#[], #[]=, #attributes, #attributes=
Constructor Details
#initialize(params = {}) ⇒ Resource
Instantiate a new resource object
338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 |
# File 'lib/jsonapi/consumer/resource.rb', line 338 def initialize(params = {}) @persisted = 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) self.class.schema.each_property do |property| attributes[property.name] = property.default unless attributes.has_key?(property.name) || property.default.nil? end 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 end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *args) ⇒ Object (protected)
482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 |
# File 'lib/jsonapi/consumer/resource.rb', line 482 def method_missing(method, *args) association = association_for(method) return super unless association || (relationships && relationships.has_attribute?(method)) return nil unless relationship_definitions = relationships[method] # look in included data if relationship_definitions.key?("data") # included.data_for returns an array, if the association is a has_one, then pick the first, otherise return the whole array if association.is_a?(JSONAPI::Consumer::Associations::HasOne::Association) return last_result_set.included.data_for(method, relationship_definitions).try(:first) else return last_result_set.included.data_for(method, relationship_definitions) end end if association = association_for(method) # look for a defined relationship url if relationship_definitions["links"] && url = relationship_definitions["links"]["related"] return association.data(url) end end nil end |
Instance Attribute Details
#last_result_set ⇒ Object
Returns the value of attribute last_result_set.
13 14 15 |
# File 'lib/jsonapi/consumer/resource.rb', line 13 def last_result_set @last_result_set end |
#links ⇒ Object
Returns the value of attribute links.
13 14 15 |
# File 'lib/jsonapi/consumer/resource.rb', line 13 def links @links end |
#relationships ⇒ Object
Returns the value of attribute relationships.
13 14 15 |
# File 'lib/jsonapi/consumer/resource.rb', line 13 def relationships @relationships end |
Class Method Details
.authorize_with(jwt, &block) ⇒ Object
Run a command wrapped in an Authorization header
164 165 166 |
# File 'lib/jsonapi/consumer/resource.rb', line 164 def (jwt, &block) with_headers(authorization: %(Bearer #{jwt}), &block) end |
.authorize_with=(jwt) ⇒ Object
Set the Authorization header to a JWT value
170 171 172 173 174 175 176 |
# File 'lib/jsonapi/consumer/resource.rb', line 170 def (jwt) if jwt.nil? self._custom_headers = {authorization: nil} else self._custom_headers = {authorization: %(Bearer #{jwt})} end end |
.authorized? ⇒ Boolean
Returns based on the presence of an Authorization header
192 193 194 |
# File 'lib/jsonapi/consumer/resource.rb', line 192 def !custom_headers[:authorization].nil? end |
.authorized_as ⇒ String
Returns The Authorization header.
185 186 187 |
# File 'lib/jsonapi/consumer/resource.rb', line 185 def custom_headers[:authorization] end |
.clear_authorization! ⇒ Object
Clears the Authorization header
180 181 182 |
# File 'lib/jsonapi/consumer/resource.rb', line 180 def self. = nil end |
.connection(rebuild = false, &block) ⇒ Connection
Return/build a connection object
101 102 103 104 |
# File 'lib/jsonapi/consumer/resource.rb', line 101 def connection(rebuild = false, &block) _build_connection(rebuild, &block) connection_object end |
.create(attributes = {}) ⇒ Resource
Create a new instance of this resource class
133 134 135 136 137 |
# File 'lib/jsonapi/consumer/resource.rb', line 133 def create(attributes = {}) new(attributes).tap do |resource| resource.save end end |
.custom_headers ⇒ Hash
The current custom headers to send with any request made by this resource class. This supports inheritance so it only needs to be set on the base class.
156 157 158 159 160 |
# File 'lib/jsonapi/consumer/resource.rb', line 156 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.
207 208 209 |
# File 'lib/jsonapi/consumer/resource.rb', line 207 def default_attributes {type: type} end |
.key_formatter ⇒ Object
218 219 220 |
# File 'lib/jsonapi/consumer/resource.rb', line 218 def key_formatter JSONAPI::Consumer::Formatter.formatter_for(json_key_format) end |
.load(params) ⇒ Resource
Load a resource object from attributes and consider it persisted
91 92 93 94 95 96 |
# File 'lib/jsonapi/consumer/resource.rb', line 91 def load(params) new(params).tap do |resource| resource.mark_as_persisted! resource.clear_changes_information end end |
.path(params = nil) ⇒ Object
Return the path or path pattern for this resource
115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/jsonapi/consumer/resource.rb', line 115 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
110 111 112 |
# File 'lib/jsonapi/consumer/resource.rb', line 110 def prefix_params _belongs_to_associations.map(&:param) end |
.requestor ⇒ Requestor
Returns the requestor for this resource class
199 200 201 |
# File 'lib/jsonapi/consumer/resource.rb', line 199 def requestor @requestor ||= requestor_class.new(self) end |
.resource_name ⇒ String
The name of a single resource. i.e. Article -> article, Person -> person
68 69 70 |
# File 'lib/jsonapi/consumer/resource.rb', line 68 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.
84 85 86 |
# File 'lib/jsonapi/consumer/resource.rb', line 84 def resource_path table_name end |
.route_formatter ⇒ Object
222 223 224 |
# File 'lib/jsonapi/consumer/resource.rb', line 222 def route_formatter JSONAPI::Consumer::Formatter.formatter_for(route_format) end |
.schema ⇒ Schema
Returns the schema for this resource class
214 215 216 |
# File 'lib/jsonapi/consumer/resource.rb', line 214 def schema @schema ||= Schema.new end |
.table_name ⇒ String
The table name for this resource. i.e. Article -> articles, Person -> people
61 62 63 |
# File 'lib/jsonapi/consumer/resource.rb', line 61 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.
76 77 78 |
# File 'lib/jsonapi/consumer/resource.rb', line 76 def type table_name end |
.with_headers(headers) ⇒ Object
Within the given block, add these headers to all requests made by the resource class
144 145 146 147 148 149 |
# File 'lib/jsonapi/consumer/resource.rb', line 144 def with_headers(headers) self._custom_headers = headers yield ensure self._custom_headers = {} end |
Instance Method Details
#as_json ⇒ Object
411 412 413 414 415 416 417 418 |
# File 'lib/jsonapi/consumer/resource.rb', line 411 def as_json(*) attributes.slice(:id, :type).tap do |h| relationships.as_json.tap do |r| h[:relationships] = r unless r.empty? end h[:attributes] = attributes.except(:id, :type).as_json end end |
#as_json_api ⇒ Hash
When we represent this resource for serialization (create/update), we do so with this implementation
402 403 404 405 406 407 408 409 |
# File 'lib/jsonapi/consumer/resource.rb', line 402 def as_json_api(*) attributes.slice(:id, :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
394 395 396 |
# File 'lib/jsonapi/consumer/resource.rb', line 394 def as_relation attributes.slice(:type, self.class.primary_key) end |
#destroy ⇒ Boolean
Try to destroy this resource
465 466 467 468 469 470 471 472 473 474 |
# File 'lib/jsonapi/consumer/resource.rb', line 465 def destroy self.last_result_set = self.class.requestor.destroy(self) if last_result_set.has_errors? fill_errors false else self.attributes.clear true end end |
#inspect ⇒ Object
476 477 478 |
# File 'lib/jsonapi/consumer/resource.rb', line 476 def inspect "#<#{self.class.name}:@attributes=#{attributes.inspect}>" end |
#mark_as_persisted! ⇒ Object
Mark the record as persisted
373 374 375 |
# File 'lib/jsonapi/consumer/resource.rb', line 373 def mark_as_persisted! @persisted = true end |
#new_record? ⇒ Boolean
Returns true if this is a new record (never persisted to the database)
387 388 389 |
# File 'lib/jsonapi/consumer/resource.rb', line 387 def new_record? !persisted? end |
#persisted? ⇒ Boolean
Whether or not this record has been persisted to the database previously
380 381 382 |
# File 'lib/jsonapi/consumer/resource.rb', line 380 def persisted? !!@persisted && has_attribute?(self.class.primary_key) 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
437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 |
# File 'lib/jsonapi/consumer/resource.rb', line 437 def save return false unless valid? 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 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 end true end end |
#set_all_dirty! ⇒ Object
Mark all attributes for this record as dirty
421 422 423 424 |
# File 'lib/jsonapi/consumer/resource.rb', line 421 def set_all_dirty! set_all_attributes_dirty relationships.set_all_attributes_dirty if relationships end |
#update(attrs = {}) ⇒ Boolean
Alias to update_attributes
368 369 370 |
# File 'lib/jsonapi/consumer/resource.rb', line 368 def update(attrs = {}) update_attributes(attrs) end |
#update_attributes(attrs = {}) ⇒ Boolean
Set the current attributes and try to save them
359 360 361 362 |
# File 'lib/jsonapi/consumer/resource.rb', line 359 def update_attributes(attrs = {}) self.attributes = attrs save end |
#valid?(context = nil) ⇒ Boolean
426 427 428 429 |
# File 'lib/jsonapi/consumer/resource.rb', line 426 def valid?(context = nil) context ||= (new_record? ? :create : :update) super(context) end |