Class: RelationToJSON::Base
- Inherits:
-
Object
- Object
- RelationToJSON::Base
- Defined in:
- lib/relation_to_json/base.rb
Instance Attribute Summary collapse
-
#relation ⇒ Object
readonly
Returns the value of attribute relation.
-
#schema ⇒ Object
readonly
Returns the value of attribute schema.
Instance Method Summary collapse
- #as_json ⇒ Object
-
#initialize(relation, schema) ⇒ Base
constructor
A new instance of Base.
Constructor Details
#initialize(relation, schema) ⇒ Base
Returns a new instance of Base.
10 11 12 13 |
# File 'lib/relation_to_json/base.rb', line 10 def initialize(relation, schema) @relation = relation @schema = schema end |
Instance Attribute Details
#relation ⇒ Object (readonly)
Returns the value of attribute relation.
8 9 10 |
# File 'lib/relation_to_json/base.rb', line 8 def relation @relation end |
#schema ⇒ Object (readonly)
Returns the value of attribute schema.
8 9 10 |
# File 'lib/relation_to_json/base.rb', line 8 def schema @schema end |
Instance Method Details
#as_json ⇒ Object
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/relation_to_json/base.rb', line 15 def as_json # put everything here, anything else is private attributes, schema_associations = schema .partition { |e| e.is_a?(Symbol) } schema_associations = schema_associations.first.dup || [] attributes = Set[:id] + attributes reflections = RelationToJSON::ReflectionBuilder.build(schema_associations, relation) schema_associations.each do |schema_association, association_attributes| reflection = reflections[schema_association] case reflection when RelationToJSON::BelongsToReflection attributes << reflection.foreign_key.to_sym when RelationToJSON::HasOneReflection association_attributes << reflection.foreign_key.to_sym end end raise_unless_all_attributes_present_on_model!(relation, attributes) result = relation .reload # if when the relation isn't loaded, it may have strange ordering .pluck(*attributes) .map { |plucked| attributes.zip(Array.wrap(plucked)).to_h } transposed = transpose(result) reflections.each do |reflection_name, reflection| foreign_key = reflection.foreign_key primary_key = reflection.primary_key # if the current schema still has associations # then we need to recursively find the JSON # representation of that association # Otherwise, we can perform a shallow .pluck # of the association attributes # and map them back onto the transposed hash # this returns an array of hashes that map association attributes to plucked values plucked_values = reflection.pluck_association_columns(transposed) case reflection when RelationToJSON::BelongsToReflection # build a temporary mapping of id => assigned_attributes associated_model_primary_key_indexed_plucked_values = plucked_values .to_h { |attrs| [attrs&.fetch(primary_key, nil), attrs] } .compact result.each do |record| foreign_key_value = record[foreign_key] plucked_values = associated_model_primary_key_indexed_plucked_values[foreign_key_value] record[reflection_name] = plucked_values record.except!(foreign_key) end when RelationToJSON::HasOneReflection # build a temporary mapping of id => assigned_attributes associated_model_foreign_key_indexed_plucked_values = plucked_values .to_h { |attrs| [attrs&.fetch(foreign_key, nil), attrs] } .compact result.each do |record| primary_key_value = record[primary_key] plucked_values = associated_model_foreign_key_indexed_plucked_values[primary_key_value] plucked_values.except!(foreign_key) if plucked_values record[reflection_name] = plucked_values end end end result&.map { |partial| partial.with_indifferent_access } end |