Class: ApiMaker::CollectionSerializer

Inherits:
Object
  • Object
show all
Defined in:
lib/api_maker/collection_serializer.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(ability: nil, api_maker_args: {}, collection:, locals: nil, model_class: nil, query_params: nil) ⇒ CollectionSerializer

Returns a new instance of CollectionSerializer.



4
5
6
7
8
9
10
11
12
13
14
15
16
# File 'lib/api_maker/collection_serializer.rb', line 4

def initialize(ability: nil, api_maker_args: {}, collection:, locals: nil, model_class: nil, query_params: nil)
  raise "No collection was given" unless collection

  @query_params = query_params || {}
  @ability = ability || ApiMaker::Ability.new(api_maker_args: api_maker_args)
  @api_maker_args = api_maker_args
  @collection = collection
  @locals = locals || api_maker_args&.dig(:locals) || {}
  @preload_param = @query_params[:preload]
  @model_class = model_class
  @select = ApiMaker::SelectParser.execute!(select: query_params[:select]) if @query_params[:select]
  @select_columns = @query_params[:select_columns]
end

Instance Attribute Details

#abilityObject (readonly)

Returns the value of attribute ability.



2
3
4
# File 'lib/api_maker/collection_serializer.rb', line 2

def ability
  @ability
end

#api_maker_argsObject (readonly)

Returns the value of attribute api_maker_args.



2
3
4
# File 'lib/api_maker/collection_serializer.rb', line 2

def api_maker_args
  @api_maker_args
end

#collectionObject (readonly)

Returns the value of attribute collection.



2
3
4
# File 'lib/api_maker/collection_serializer.rb', line 2

def collection
  @collection
end

#localsObject (readonly)

Returns the value of attribute locals.



2
3
4
# File 'lib/api_maker/collection_serializer.rb', line 2

def locals
  @locals
end

#preload_paramObject (readonly)

Returns the value of attribute preload_param.



2
3
4
# File 'lib/api_maker/collection_serializer.rb', line 2

def preload_param
  @preload_param
end

#query_paramsObject (readonly)

Returns the value of attribute query_params.



2
3
4
# File 'lib/api_maker/collection_serializer.rb', line 2

def query_params
  @query_params
end

#selectObject (readonly)

Returns the value of attribute select.



2
3
4
# File 'lib/api_maker/collection_serializer.rb', line 2

def select
  @select
end

#select_columnsObject (readonly)

Returns the value of attribute select_columns.



2
3
4
# File 'lib/api_maker/collection_serializer.rb', line 2

def select_columns
  @select_columns
end

Instance Method Details

#add_model_to_records(model, data, records) ⇒ Object



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/api_maker/collection_serializer.rb', line 49

def add_model_to_records(model, data, records)
  serializer = serializer_for_model(model)
  resource = serializer.resource
  collection_name = resource.collection_name
  records[collection_name] ||= {}

  if model.new_record?
    id = "new-#{records.fetch(collection_name).length}"
  else
    id = ApiMaker::PrimaryIdForModel.get(model)
  end

  data.fetch(:preloaded)[collection_name] ||= {}
  data.fetch(:preloaded)[collection_name][id] ||= serializer

  data.fetch(:data)[collection_name] ||= []
  data.fetch(:data)[collection_name] << id

  records[collection_name][id] ||= serializer
end

#as_json(options = nil) ⇒ Object



70
71
72
# File 'lib/api_maker/collection_serializer.rb', line 70

def as_json(options = nil)
  result.as_json(options)
end

#load_abilities(data) ⇒ Object



37
38
39
40
41
42
43
44
45
46
47
# File 'lib/api_maker/collection_serializer.rb', line 37

def load_abilities(data)
  data.fetch(:preloaded).each_value do |models|
    next if models.empty?

    serializers = models.values
    serializer = models.values.first
    abilities = query_params.dig(:abilities, serializer.resource.require_name)

    ApiMaker::AbilitiesLoader.execute!(abilities: abilities, ability: ability, serializers: serializers) if abilities && serializers
  end
end

#model_classObject



74
75
76
77
78
79
80
# File 'lib/api_maker/collection_serializer.rb', line 74

def model_class
  @model_class ||= if collection.is_a?(Array)
    collection.first.class
  else
    resource.model_class
  end
end

#parsed_collectionObject



90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/api_maker/collection_serializer.rb', line 90

def parsed_collection
  @parsed_collection ||= begin
    new_collection = ApiMaker::SelectColumnsOnCollection.execute!(
      collection: collection,
      model_class: model_class,
      select_attributes: select,
      select_columns: select_columns
    )
    new_collection = new_collection.fix if !new_collection.is_a?(Array) && ApiMaker::DatabaseType.postgres?
    new_collection
  end
end

#preload_collection(data, records) ⇒ Object



103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/api_maker/collection_serializer.rb', line 103

def preload_collection(data, records)
  preloader = ApiMaker::Preloader.new(
    ability: ability,
    api_maker_args: api_maker_args,
    collection: parsed_collection,
    data: data,
    locals: locals,
    preload_param: preload_param,
    model_class: model_class,
    records: records,
    select: select,
    select_columns: select_columns
  )
  preloader.fill_data
end

#resourceObject



82
83
84
85
86
87
88
# File 'lib/api_maker/collection_serializer.rb', line 82

def resource
  @resource ||= if collection.is_a?(Array)
    ApiMaker::MemoryStorage.current.resource_for_model(collection.first.class)
  else
    ApiMaker::MemoryStorage.current.resource_for_model(collection.klass)
  end
end

#resultObject



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/api_maker/collection_serializer.rb', line 18

def result
  @result ||= begin
    data = {
      data: {},
      preloaded: {}
    }

    records = {}
    parsed_collection.map do |model|
      add_model_to_records(model, data, records)
    end

    preload_collection(data, records) if parsed_collection.length.positive?
    load_abilities(data) if query_params[:abilities]

    data
  end
end

#select_for(model) ⇒ Object



119
120
121
# File 'lib/api_maker/collection_serializer.rb', line 119

def select_for(model)
  select&.dig(model.class)
end

#serializer_for_model(model) ⇒ Object



123
124
125
# File 'lib/api_maker/collection_serializer.rb', line 123

def serializer_for_model(model)
  ApiMaker::Serializer.new(ability: ability, api_maker_args: api_maker_args, locals: locals, model: model, select: select_for(model))
end

#to_json(options = nil) ⇒ Object



127
128
129
# File 'lib/api_maker/collection_serializer.rb', line 127

def to_json(options = nil)
  JSON.generate(as_json(options))
end