Class: JSONAPI::Resource
- Inherits:
-
Object
- Object
- JSONAPI::Resource
- Includes:
- Callbacks, ResourceFor
- Defined in:
- lib/jsonapi/resource.rb
Constant Summary collapse
- @@resource_types =
{}
Class Attribute Summary collapse
-
._allowed_filters ⇒ Object
Returns the value of attribute _allowed_filters.
-
._associations ⇒ Object
Returns the value of attribute _associations.
-
._attributes ⇒ Object
Returns the value of attribute _attributes.
-
._type ⇒ Object
Returns the value of attribute _type.
Instance Attribute Summary collapse
-
#context ⇒ Object
readonly
Returns the value of attribute context.
-
#model ⇒ Object
readonly
Returns the value of attribute model.
Class Method Summary collapse
-
._allowed_filter?(filter) ⇒ Boolean
:nocov:.
- ._as_parent_key ⇒ Object
- ._association(type) ⇒ Object
-
._attribute_options(attr) ⇒ Object
quasi private class methods.
- ._has_association?(type) ⇒ Boolean
- ._key ⇒ Object
- ._model_name ⇒ Object
- ._primary_key ⇒ Object
- ._resource_name_from_type(type) ⇒ Object
- ._updateable_associations ⇒ Object
- .apply_filter(records, filter, value) ⇒ Object
- .attribute(attr, options = {}) ⇒ Object
-
.attributes(*attrs) ⇒ Object
Methods used in defining a resource class.
- .create(context) ⇒ Object
- .create_model ⇒ Object
-
.createable_fields(context = nil) ⇒ Object
Override in your resource to filter the createable keys.
- .default_attribute_options ⇒ Object
- .fields ⇒ Object
- .filter(attr) ⇒ Object
- .filters(*attrs) ⇒ Object
-
.find(filters, options = {}) ⇒ Object
Override this method if you have more complex requirements than this basic find method provides.
- .find_by_key(key, options = {}) ⇒ Object
- .find_by_keys(keys, options = {}) ⇒ Object
- .has_many(*attrs) ⇒ Object
- .has_one(*attrs) ⇒ Object
- .inherited(base) ⇒ Object
- .is_filter_association?(filter) ⇒ Boolean
- .key(key) ⇒ Object
- .model_name(model) ⇒ Object
- .module_path ⇒ Object
- .primary_key(key) ⇒ Object
-
.records(options = {}) ⇒ Object
Override this method if you want to customize the relation for finder methods (find, find_by_key, find_by_keys).
- .routing_options(options) ⇒ Object
- .routing_resource_options ⇒ Object
-
.sortable_fields(context = nil) ⇒ Object
Override in your resource to filter the sortable keys.
-
.updateable_fields(context = nil) ⇒ Object
Override in your resource to filter the updateable keys.
-
.verify_association_filter(filter, raw, context = nil) ⇒ Object
override to allow for custom association logic, such as uuids, multiple keys or permission checks on keys.
-
.verify_custom_filter(filter, value, context = nil) ⇒ Object
override to allow for custom filters.
- .verify_filter(filter, raw, context = nil) ⇒ Object
- .verify_filters(filters, context = nil) ⇒ Object
-
.verify_key(key, context = nil) ⇒ Object
override to allow for key processing and checking.
-
.verify_keys(keys, context = nil) ⇒ Object
override to allow for key processing and checking.
Instance Method Summary collapse
- #_model_class ⇒ Object
- #change(callback) ⇒ Object
- #create_has_many_links(association_type, association_key_values) ⇒ Object
- #create_has_one_link(association_type, association_key_value) ⇒ Object
-
#fetchable_fields ⇒ Object
Override this on a resource instance to override the fetchable keys.
- #id ⇒ Object
-
#initialize(model, context = nil) ⇒ Resource
constructor
A new instance of Resource.
- #is_new? ⇒ Boolean
- #remove ⇒ Object
- #remove_has_many_link(association_type, key) ⇒ Object
- #remove_has_one_link(association_type) ⇒ Object
- #replace_fields(field_data) ⇒ Object
- #replace_has_many_links(association_type, association_key_values) ⇒ Object
- #replace_has_one_link(association_type, association_key_value) ⇒ Object
Methods included from Callbacks
Methods included from ResourceFor
Constructor Details
#initialize(model, context = nil) ⇒ Resource
Returns a new instance of Resource.
28 29 30 31 |
# File 'lib/jsonapi/resource.rb', line 28 def initialize(model, context = nil) @model = model @context = context end |
Class Attribute Details
._allowed_filters ⇒ Object
Returns the value of attribute _allowed_filters.
226 227 228 |
# File 'lib/jsonapi/resource.rb', line 226 def _allowed_filters @_allowed_filters end |
._associations ⇒ Object
Returns the value of attribute _associations.
226 227 228 |
# File 'lib/jsonapi/resource.rb', line 226 def _associations @_associations end |
._attributes ⇒ Object
Returns the value of attribute _attributes.
226 227 228 |
# File 'lib/jsonapi/resource.rb', line 226 def _attributes @_attributes end |
._type ⇒ Object
Returns the value of attribute _type.
226 227 228 |
# File 'lib/jsonapi/resource.rb', line 226 def _type @_type end |
Instance Attribute Details
#context ⇒ Object (readonly)
Returns the value of attribute context.
13 14 15 |
# File 'lib/jsonapi/resource.rb', line 13 def context @context end |
#model ⇒ Object (readonly)
Returns the value of attribute model.
14 15 16 |
# File 'lib/jsonapi/resource.rb', line 14 def model @model end |
Class Method Details
._allowed_filter?(filter) ⇒ Boolean
:nocov:
495 496 497 |
# File 'lib/jsonapi/resource.rb', line 495 def _allowed_filter?(filter) _allowed_filters.include?(filter) end |
._as_parent_key ⇒ Object
466 467 468 |
# File 'lib/jsonapi/resource.rb', line 466 def _as_parent_key @_as_parent_key ||= "#{_type.to_s.singularize}_#{_primary_key}" end |
._association(type) ⇒ Object
446 447 448 449 |
# File 'lib/jsonapi/resource.rb', line 446 def _association(type) type = type.to_sym @_associations[type] end |
._attribute_options(attr) ⇒ Object
quasi private class methods
426 427 428 |
# File 'lib/jsonapi/resource.rb', line 426 def (attr) .merge(@_attributes[attr]) end |
._has_association?(type) ⇒ Boolean
441 442 443 444 |
# File 'lib/jsonapi/resource.rb', line 441 def _has_association?(type) type = type.to_s @_associations.has_key?(type.singularize.to_sym) || @_associations.has_key?(type.pluralize.to_sym) end |
._key ⇒ Object
455 456 457 458 459 460 |
# File 'lib/jsonapi/resource.rb', line 455 def _key # :nocov: warn '[DEPRECATION] `_key` is deprecated. Please use `_primary_key` instead.' _primary_key # :nocov: end |
._model_name ⇒ Object
451 452 453 |
# File 'lib/jsonapi/resource.rb', line 451 def _model_name @_model_name ||= self.name.demodulize.sub(/Resource$/, '') end |
._primary_key ⇒ Object
462 463 464 |
# File 'lib/jsonapi/resource.rb', line 462 def _primary_key @_primary_key ||= :id end |
._resource_name_from_type(type) ⇒ Object
474 475 476 477 478 479 480 481 |
# File 'lib/jsonapi/resource.rb', line 474 def _resource_name_from_type(type) class_name = @@resource_types[type] if class_name.nil? class_name = type.to_s.singularize.camelize + 'Resource' @@resource_types[type] = class_name end return class_name end |
._updateable_associations ⇒ Object
430 431 432 433 434 435 436 437 438 439 |
# File 'lib/jsonapi/resource.rb', line 430 def _updateable_associations associations = [] @_associations.each do |key, association| if association.is_a?(JSONAPI::Association::HasOne) || association.acts_as_set associations.push(key) end end associations end |
.apply_filter(records, filter, value) ⇒ Object
318 319 320 |
# File 'lib/jsonapi/resource.rb', line 318 def apply_filter(records, filter, value) records.where(filter => value) end |
.attribute(attr, options = {}) ⇒ Object
251 252 253 254 255 256 257 258 259 260 261 262 |
# File 'lib/jsonapi/resource.rb', line 251 def attribute(attr, = {}) check_reserved_attribute_name(attr) @_attributes[attr] = define_method attr do @model.send(attr) end unless method_defined?(attr) define_method "#{attr}=" do |value| @model.send "#{attr}=", value end unless method_defined?("#{attr}=") end |
.attributes(*attrs) ⇒ Object
Methods used in defining a resource class
245 246 247 248 249 |
# File 'lib/jsonapi/resource.rb', line 245 def attributes(*attrs) attrs.each do |attr| attribute(attr) end end |
.create(context) ⇒ Object
228 229 230 |
# File 'lib/jsonapi/resource.rb', line 228 def create(context) self.new(self.create_model, context) end |
.create_model ⇒ Object
232 233 234 |
# File 'lib/jsonapi/resource.rb', line 232 def create_model _model_class.new end |
.createable_fields(context = nil) ⇒ Object
Override in your resource to filter the createable keys
305 306 307 |
# File 'lib/jsonapi/resource.rb', line 305 def createable_fields(context = nil) _updateable_associations | _attributes.keys end |
.default_attribute_options ⇒ Object
264 265 266 |
# File 'lib/jsonapi/resource.rb', line 264 def {format: :default} end |
.fields ⇒ Object
314 315 316 |
# File 'lib/jsonapi/resource.rb', line 314 def fields _associations.keys | _attributes.keys end |
.filter(attr) ⇒ Object
284 285 286 |
# File 'lib/jsonapi/resource.rb', line 284 def filter(attr) @_allowed_filters.add(attr.to_sym) end |
.filters(*attrs) ⇒ Object
280 281 282 |
# File 'lib/jsonapi/resource.rb', line 280 def filters(*attrs) @_allowed_filters.merge(attrs) end |
.find(filters, options = {}) ⇒ Object
Override this method if you have more complex requirements than this basic find method provides
323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 |
# File 'lib/jsonapi/resource.rb', line 323 def find(filters, = {}) context = [:context] sort_params = .fetch(:sort_params) { [] } includes = [] records = records() filters.each do |filter, value| if _associations.include?(filter) if _associations[filter].is_a?(JSONAPI::Association::HasMany) includes.push(filter) records = apply_filter(records, "#{filter}.#{_associations[filter].primary_key}", value) else records = apply_filter(records, "#{_associations[filter].foreign_key}", value) end else records = apply_filter(records, filter, value) end end resources = [] = (sort_params) records.order().includes(includes).each do |model| resources.push self.new(model, context) end return resources end |
.find_by_key(key, options = {}) ⇒ Object
352 353 354 355 356 357 358 359 |
# File 'lib/jsonapi/resource.rb', line 352 def find_by_key(key, = {}) context = [:context] model = records().where({_primary_key => key}).first if model.nil? raise JSONAPI::Exceptions::RecordNotFound.new(key) end self.new(model, context) end |
.find_by_keys(keys, options = {}) ⇒ Object
361 362 363 364 365 366 367 368 369 370 371 |
# File 'lib/jsonapi/resource.rb', line 361 def find_by_keys(keys, = {}) context = [:context] _models = records().where({_primary_key => keys}) unless _models.length == keys.length key = (keys - _models.pluck(_primary_key).map(&:to_s)).first raise JSONAPI::Exceptions::RecordNotFound.new(key) end _models.map { |model| self.new(model, context) } end |
.has_many(*attrs) ⇒ Object
272 273 274 |
# File 'lib/jsonapi/resource.rb', line 272 def has_many(*attrs) _associate(Association::HasMany, *attrs) end |
.has_one(*attrs) ⇒ Object
268 269 270 |
# File 'lib/jsonapi/resource.rb', line 268 def has_one(*attrs) _associate(Association::HasOne, *attrs) end |
.inherited(base) ⇒ Object
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 |
# File 'lib/jsonapi/resource.rb', line 210 def inherited(base) base._attributes = (_attributes || {}).dup base._associations = (_associations || {}).dup base._allowed_filters = (_allowed_filters || Set.new).dup type = base.name.demodulize.sub(/Resource$/, '').underscore base._type = type.pluralize.to_sym check_reserved_resource_name(base._type, base.name) # If eager loading is on this is how all the resource types are setup # If eager loading is off some resource types will be initialized in # _resource_name_from_type @@resource_types[base._type] ||= base.name.demodulize end |
.is_filter_association?(filter) ⇒ Boolean
388 389 390 |
# File 'lib/jsonapi/resource.rb', line 388 def is_filter_association?(filter) filter == _type || _associations.include?(filter) end |
.key(key) ⇒ Object
288 289 290 291 292 293 |
# File 'lib/jsonapi/resource.rb', line 288 def key(key) # :nocov: warn '[DEPRECATION] `key` is deprecated. Please use `primary_key` instead.' @_primary_key = key.to_sym # :nocov: end |
.model_name(model) ⇒ Object
276 277 278 |
# File 'lib/jsonapi/resource.rb', line 276 def model_name(model) @_model_name = model.to_sym end |
.module_path ⇒ Object
499 500 501 |
# File 'lib/jsonapi/resource.rb', line 499 def module_path @module_path ||= self.name =~ /::[^:]+\Z/ ? ($`.freeze.gsub('::', '/') + '/').downcase : '' end |
.primary_key(key) ⇒ Object
295 296 297 |
# File 'lib/jsonapi/resource.rb', line 295 def primary_key(key) @_primary_key = key.to_sym end |
.records(options = {}) ⇒ Object
Override this method if you want to customize the relation for finder methods (find, find_by_key, find_by_keys)
375 376 377 |
# File 'lib/jsonapi/resource.rb', line 375 def records( = {}) _model_class end |
.routing_options(options) ⇒ Object
236 237 238 |
# File 'lib/jsonapi/resource.rb', line 236 def () @_routing_resource_options = end |
.routing_resource_options ⇒ Object
240 241 242 |
# File 'lib/jsonapi/resource.rb', line 240 def @_routing_resource_options ||= {} end |
.sortable_fields(context = nil) ⇒ Object
Override in your resource to filter the sortable keys
310 311 312 |
# File 'lib/jsonapi/resource.rb', line 310 def sortable_fields(context = nil) _attributes.keys end |
.updateable_fields(context = nil) ⇒ Object
Override in your resource to filter the updateable keys
300 301 302 |
# File 'lib/jsonapi/resource.rb', line 300 def updateable_fields(context = nil) _updateable_associations | _attributes.keys end |
.verify_association_filter(filter, raw, context = nil) ⇒ Object
override to allow for custom association logic, such as uuids, multiple keys or permission checks on keys
421 422 423 |
# File 'lib/jsonapi/resource.rb', line 421 def verify_association_filter(filter, raw, context = nil) return filter, raw end |
.verify_custom_filter(filter, value, context = nil) ⇒ Object
override to allow for custom filters
416 417 418 |
# File 'lib/jsonapi/resource.rb', line 416 def verify_custom_filter(filter, value, context = nil) return filter, value end |
.verify_filter(filter, raw, context = nil) ⇒ Object
392 393 394 395 396 397 398 399 400 401 |
# File 'lib/jsonapi/resource.rb', line 392 def verify_filter(filter, raw, context = nil) filter_values = [] filter_values += CSV.parse_line(raw) unless raw.nil? || raw.empty? if is_filter_association?(filter) verify_association_filter(filter, filter_values, context) else verify_custom_filter(filter, filter_values, context) end end |
.verify_filters(filters, context = nil) ⇒ Object
379 380 381 382 383 384 385 386 |
# File 'lib/jsonapi/resource.rb', line 379 def verify_filters(filters, context = nil) verified_filters = {} filters.each do |filter, raw_value| verified_filter = verify_filter(filter, raw_value, context) verified_filters[verified_filter[0]] = verified_filter[1] end verified_filters end |
.verify_key(key, context = nil) ⇒ Object
override to allow for key processing and checking
404 405 406 |
# File 'lib/jsonapi/resource.rb', line 404 def verify_key(key, context = nil) return key end |
.verify_keys(keys, context = nil) ⇒ Object
override to allow for key processing and checking
409 410 411 412 413 |
# File 'lib/jsonapi/resource.rb', line 409 def verify_keys(keys, context = nil) return keys.collect do |key| verify_key(key, context) end end |
Instance Method Details
#_model_class ⇒ Object
485 486 487 |
# File 'lib/jsonapi/resource.rb', line 485 def _model_class @model ||= Object.const_get(_model_name.to_s) end |
#change(callback) ⇒ Object
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/jsonapi/resource.rb', line 41 def change(callback) if @changing run_callbacks callback do yield end else run_callbacks is_new? ? :create : :update do @changing = true run_callbacks callback do yield save if @save_needed end end end end |
#create_has_many_links(association_type, association_key_values) ⇒ Object
63 64 65 66 67 |
# File 'lib/jsonapi/resource.rb', line 63 def create_has_many_links(association_type, association_key_values) change :create_has_many_link do _create_has_many_links(association_type, association_key_values) end end |
#create_has_one_link(association_type, association_key_value) ⇒ Object
75 76 77 78 79 |
# File 'lib/jsonapi/resource.rb', line 75 def create_has_one_link(association_type, association_key_value) change :create_has_one_link do _create_has_one_link(association_type, association_key_value) end end |
#fetchable_fields ⇒ Object
Override this on a resource instance to override the fetchable keys
106 107 108 |
# File 'lib/jsonapi/resource.rb', line 106 def fetchable_fields self.class.fields end |
#id ⇒ Object
33 34 35 |
# File 'lib/jsonapi/resource.rb', line 33 def id model.send(self.class._primary_key) end |
#is_new? ⇒ Boolean
37 38 39 |
# File 'lib/jsonapi/resource.rb', line 37 def is_new? id.nil? end |
#remove ⇒ Object
57 58 59 60 61 |
# File 'lib/jsonapi/resource.rb', line 57 def remove run_callbacks :remove do _remove end end |
#remove_has_many_link(association_type, key) ⇒ Object
87 88 89 90 91 |
# File 'lib/jsonapi/resource.rb', line 87 def remove_has_many_link(association_type, key) change :remove_has_many_link do _remove_has_many_link(association_type, key) end end |
#remove_has_one_link(association_type) ⇒ Object
93 94 95 96 97 |
# File 'lib/jsonapi/resource.rb', line 93 def remove_has_one_link(association_type) change :remove_has_one_link do _remove_has_one_link(association_type) end end |
#replace_fields(field_data) ⇒ Object
99 100 101 102 103 |
# File 'lib/jsonapi/resource.rb', line 99 def replace_fields(field_data) change :replace_fields do _replace_fields(field_data) end end |
#replace_has_many_links(association_type, association_key_values) ⇒ Object
69 70 71 72 73 |
# File 'lib/jsonapi/resource.rb', line 69 def replace_has_many_links(association_type, association_key_values) change :replace_has_many_links do _replace_has_many_links(association_type, association_key_values) end end |
#replace_has_one_link(association_type, association_key_value) ⇒ Object
81 82 83 84 85 |
# File 'lib/jsonapi/resource.rb', line 81 def replace_has_one_link(association_type, association_key_value) change :replace_has_one_link do _replace_has_one_link(association_type, association_key_value) end end |