class FunWithJsonApi::Attributes::RelationshipCollection
Attributes
deserializer_class[R]
options[R]
Public Class Methods
create(name, deserializer_class_or_callable, options = {})
click to toggle source
# File lib/fun_with_json_api/attributes/relationship_collection.rb, line 6 def self.create(name, deserializer_class_or_callable, options = {}) new(name, deserializer_class_or_callable, options) end
new(name, deserializer_class, options = {})
click to toggle source
Calls superclass method
FunWithJsonApi::Attribute::new
# File lib/fun_with_json_api/attributes/relationship_collection.rb, line 14 def initialize(name, deserializer_class, options = {}) options = options.reverse_merge( attributes: [], relationships: [] ) super(name, options) @deserializer_class = deserializer_class end
Public Instance Methods
decode(values)
click to toggle source
Expects an array of id values for a nested collection
# File lib/fun_with_json_api/attributes/relationship_collection.rb, line 24 def decode(values) unless values.nil? || values.is_a?(Array) raise build_invalid_relationship_collection_error(values) end collection = deserializer.load_collection_from_id_values(values) # Ensure the collection size matches check_collection_matches_values!(collection, values) # Ensure the user is authorized to access the collection check_collection_is_authorized!(collection, values) # Call ActiceRecord#pluck if it is available convert_collection_to_ids(collection) end
deserializer()
click to toggle source
# File lib/fun_with_json_api/attributes/relationship_collection.rb, line 54 def deserializer @deserializer ||= build_deserializer_from_options end
has_many?()
click to toggle source
rubocop:disable Style/PredicateName
# File lib/fun_with_json_api/attributes/relationship_collection.rb, line 43 def has_many? true end
param_value()
click to toggle source
User the singular of ‘as` that is how AMS converts the value
# File lib/fun_with_json_api/attributes/relationship_collection.rb, line 50 def param_value :"#{as.to_s.singularize}_ids" end
Private Instance Methods
build_deserializer_from_options()
click to toggle source
# File lib/fun_with_json_api/attributes/relationship_collection.rb, line 60 def build_deserializer_from_options if @deserializer_class.respond_to?(:call) @deserializer_class.call else @deserializer_class end.create(options) end
build_invalid_relationship_collection_error(values)
click to toggle source
# File lib/fun_with_json_api/attributes/relationship_collection.rb, line 90 def build_invalid_relationship_collection_error(values) exception_message = "#{name} relationship should contain a array of"\ " '#{deserializer.type}' data" payload = ExceptionPayload.new payload.pointer = "/data/relationships/#{name}/data" payload.detail = exception_message Exceptions::InvalidRelationship.new(exception_message + ": #{values.inspect}", payload) end
build_missing_relationship_error_from_collection(collection, values)
click to toggle source
# File lib/fun_with_json_api/attributes/relationship_collection.rb, line 99 def build_missing_relationship_error_from_collection(collection, values) collection_ids = deserializer.format_collection_ids(collection) payload = build_missing_relationship_payload(collection_ids, values) missing_values = values.reject { |value| collection_ids.include?(value.to_s) } exception_message = "Couldn't find #{deserializer.resource_class} items with "\ "#{deserializer.id_param} in #{missing_values.inspect}" Exceptions::MissingRelationship.new(exception_message, payload) end
build_missing_relationship_payload(collection_ids, values)
click to toggle source
# File lib/fun_with_json_api/attributes/relationship_collection.rb, line 110 def build_missing_relationship_payload(collection_ids, values) values.each_with_index.map do |resource_id, index| next if collection_ids.include?(resource_id) ExceptionPayload.new.tap do |payload| payload.pointer = "/data/relationships/#{name}/data/#{index}" payload.detail = "Unable to find '#{deserializer.type}' with matching id"\ ": \"#{resource_id}\"" end end.reject(&:nil?) end
check_collection_matches_values!(collection, values)
click to toggle source
# File lib/fun_with_json_api/attributes/relationship_collection.rb, line 68 def check_collection_matches_values!(collection, values) expected_size = values.size result_size = collection.size if result_size != expected_size raise build_missing_relationship_error_from_collection(collection, values) end end
convert_collection_to_ids(collection)
click to toggle source
# File lib/fun_with_json_api/attributes/relationship_collection.rb, line 82 def convert_collection_to_ids(collection) if collection.respond_to? :pluck # Well... pluck+arel doesn't work with SQLite, but select at least is safe collection = collection.select(deserializer.resource_class.arel_table[:id]) end collection.map(&:id) end