forest_liana 2.15.8 → 3.0.0.pre.beta.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +1 -1
  3. data/app/controllers/forest_liana/resources_controller.rb +9 -17
  4. data/app/controllers/forest_liana/stats_controller.rb +4 -14
  5. data/app/models/forest_liana/model/action.rb +57 -3
  6. data/app/models/forest_liana/model/collection.rb +37 -9
  7. data/app/models/forest_liana/model/segment.rb +1 -1
  8. data/app/serializers/forest_liana/schema_serializer.rb +83 -0
  9. data/app/serializers/forest_liana/serializer_factory.rb +13 -48
  10. data/app/services/forest_liana/apimap_sorter.rb +88 -48
  11. data/app/services/forest_liana/base_getter.rb +1 -7
  12. data/app/services/forest_liana/has_many_getter.rb +14 -15
  13. data/app/services/forest_liana/line_stat_getter.rb +5 -1
  14. data/app/services/forest_liana/operator_value_parser.rb +1 -46
  15. data/app/services/forest_liana/pie_stat_getter.rb +2 -2
  16. data/app/services/forest_liana/query_stat_getter.rb +3 -25
  17. data/app/services/forest_liana/resource_getter.rb +8 -2
  18. data/app/services/forest_liana/resources_getter.rb +13 -27
  19. data/app/services/forest_liana/schema_adapter.rb +65 -64
  20. data/app/services/forest_liana/search_query_builder.rb +24 -5
  21. data/app/services/forest_liana/stat_getter.rb +8 -1
  22. data/app/services/forest_liana/value_stat_getter.rb +2 -2
  23. data/lib/forest_liana.rb +2 -0
  24. data/lib/forest_liana/bootstraper.rb +119 -122
  25. data/lib/forest_liana/collection.rb +41 -12
  26. data/lib/forest_liana/engine.rb +16 -11
  27. data/lib/forest_liana/json_printer.rb +54 -0
  28. data/lib/forest_liana/schema_file_updater.rb +141 -0
  29. data/lib/forest_liana/version.rb +1 -1
  30. data/test/dummy/config/routes.rb +1 -0
  31. data/test/dummy/db/test.sqlite3 +0 -0
  32. data/test/dummy/log/test.log +116056 -3826
  33. data/test/integration/navigation_test.rb +10 -0
  34. data/test/routing/route_test.rb +2 -0
  35. data/test/services/forest_liana/resources_getter_test.rb +3 -3
  36. data/test/services/forest_liana/schema_adapter_test.rb +50 -49
  37. metadata +11 -111
  38. data/app/helpers/forest_liana/query_helper.rb +0 -30
  39. data/app/helpers/forest_liana/schema_helper.rb +0 -8
  40. data/app/serializers/forest_liana/action_serializer.rb +0 -21
  41. data/app/serializers/forest_liana/collection_serializer.rb +0 -33
  42. data/app/serializers/forest_liana/segment_serializer.rb +0 -15
  43. data/app/services/forest_liana/leaderboard_stat_getter.rb +0 -44
  44. data/app/services/forest_liana/objective_stat_getter.rb +0 -10
  45. data/spec/dummy/README.rdoc +0 -28
  46. data/spec/dummy/Rakefile +0 -6
  47. data/spec/dummy/app/assets/javascripts/application.js +0 -13
  48. data/spec/dummy/app/assets/stylesheets/application.css +0 -15
  49. data/spec/dummy/app/config/routes.rb +0 -3
  50. data/spec/dummy/app/controllers/application_controller.rb +0 -5
  51. data/spec/dummy/app/helpers/application_helper.rb +0 -2
  52. data/spec/dummy/app/models/island.rb +0 -5
  53. data/spec/dummy/app/models/tree.rb +0 -5
  54. data/spec/dummy/app/models/user.rb +0 -4
  55. data/spec/dummy/app/views/layouts/application.html.erb +0 -14
  56. data/spec/dummy/bin/bundle +0 -3
  57. data/spec/dummy/bin/rails +0 -4
  58. data/spec/dummy/bin/rake +0 -4
  59. data/spec/dummy/bin/setup +0 -29
  60. data/spec/dummy/config.ru +0 -4
  61. data/spec/dummy/config/application.rb +0 -26
  62. data/spec/dummy/config/boot.rb +0 -5
  63. data/spec/dummy/config/database.yml +0 -25
  64. data/spec/dummy/config/environment.rb +0 -5
  65. data/spec/dummy/config/environments/development.rb +0 -41
  66. data/spec/dummy/config/environments/production.rb +0 -79
  67. data/spec/dummy/config/environments/test.rb +0 -42
  68. data/spec/dummy/config/initializers/assets.rb +0 -11
  69. data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -7
  70. data/spec/dummy/config/initializers/cookies_serializer.rb +0 -3
  71. data/spec/dummy/config/initializers/filter_parameter_logging.rb +0 -4
  72. data/spec/dummy/config/initializers/forest_liana.rb +0 -2
  73. data/spec/dummy/config/initializers/inflections.rb +0 -16
  74. data/spec/dummy/config/initializers/mime_types.rb +0 -4
  75. data/spec/dummy/config/initializers/session_store.rb +0 -3
  76. data/spec/dummy/config/initializers/wrap_parameters.rb +0 -14
  77. data/spec/dummy/config/routes.rb +0 -3
  78. data/spec/dummy/config/secrets.yml +0 -22
  79. data/spec/dummy/db/migrate/20190226172951_create_user.rb +0 -9
  80. data/spec/dummy/db/migrate/20190226173051_create_isle.rb +0 -10
  81. data/spec/dummy/db/migrate/20190226174951_create_tree.rb +0 -12
  82. data/spec/dummy/db/schema.rb +0 -42
  83. data/spec/dummy/db/test.sqlite3 +0 -0
  84. data/spec/dummy/log/development.log +0 -80
  85. data/spec/dummy/log/test.log +0 -26139
  86. data/spec/helpers/forest_liana/query_helper_spec.rb +0 -74
  87. data/spec/helpers/forest_liana/schema_helper_spec.rb +0 -13
  88. data/spec/rails_helper.rb +0 -61
  89. data/spec/requests/resources_spec.rb +0 -97
  90. data/spec/services/forest_liana/apimap_sorter_spec.rb +0 -172
  91. data/spec/services/forest_liana/ip_whitelist_checker_spec.rb +0 -203
  92. data/spec/services/forest_liana/schema_adapter_spec.rb +0 -17
  93. data/spec/spec_helper.rb +0 -99
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9791d00f328850811605eff107ed34a518693051
4
- data.tar.gz: 17321641b3f1432ec4bfb63b36a8add62a7493a3
3
+ metadata.gz: 0e4fb230ea35b62c0104cd977a4f072d21ada6d7
4
+ data.tar.gz: 82caa0a2892b39222840c79689c49354ccb387b7
5
5
  SHA512:
6
- metadata.gz: 6e82b22b8081c3b734af33a21c25b830ea27a6b6441c885ef498ab46d32586a885bc0849d3a00f2248859a7ff8e9f208f62f23f6c38b1d116c2b803c6944688f
7
- data.tar.gz: 40fae318883c99ccc3f48e634b652a158181fb0e3bd95b04bc61083a799f7f6ece1e6fc4715b00ae1c3f6139446dcee0e6c88bdd88dcf4bc73aa28325daf45a7
6
+ metadata.gz: 1994b07deb2e1a14cf6de0ebc22e431fd3cd5b5dcdc34e92847a7ec20585d4cd3961d2df41e252b82836b79dade492812a5007136e62bddd9e2370762c044a0a
7
+ data.tar.gz: 0a20dc05da425189c52941c29be9b503f0edeeed8545ca7f1040a7f3babfb15d0c281359b9089653e502ddcf5923fbeea1a97353e2fadce0e2697711d7c696ba
data/Rakefile CHANGED
@@ -14,7 +14,7 @@ RDoc::Task.new(:rdoc) do |rdoc|
14
14
  rdoc.rdoc_files.include('lib/**/*.rb')
15
15
  end
16
16
 
17
- APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
17
+ APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
18
18
  load 'rails/tasks/engine.rake'
19
19
 
20
20
 
@@ -83,7 +83,8 @@ module ForestLiana
83
83
  getter = ForestLiana::ResourceGetter.new(@resource, params)
84
84
  getter.perform
85
85
 
86
- render serializer: nil, json: render_record_jsonapi(getter.record)
86
+ render serializer: nil, json:
87
+ serialize_model(get_record(getter.record), include: includes(getter))
87
88
  rescue => error
88
89
  FOREST_LOGGER.error "Record Show error: #{error}\n#{format_stacktrace(error)}"
89
90
  internal_server_error
@@ -102,7 +103,8 @@ module ForestLiana
102
103
  render serializer: nil, json: JSONAPI::Serializer.serialize_errors(
103
104
  creator.errors), status: 400
104
105
  elsif creator.record.valid?
105
- render serializer: nil, json: render_record_jsonapi(creator.record)
106
+ render serializer: nil,
107
+ json: serialize_model(get_record(creator.record), include: record_includes)
106
108
  else
107
109
  render serializer: nil, json: JSONAPI::Serializer.serialize_errors(
108
110
  creator.record.errors), status: 400
@@ -125,7 +127,8 @@ module ForestLiana
125
127
  render serializer: nil, json: JSONAPI::Serializer.serialize_errors(
126
128
  updater.errors), status: 400
127
129
  elsif updater.record.valid?
128
- render serializer: nil, json: render_record_jsonapi(updater.record)
130
+ render serializer: nil,
131
+ json: serialize_model(get_record(updater.record), include: record_includes)
129
132
  else
130
133
  render serializer: nil, json: JSONAPI::Serializer.serialize_errors(
131
134
  updater.record.errors), status: 400
@@ -170,7 +173,9 @@ module ForestLiana
170
173
  end
171
174
 
172
175
  def record_includes
173
- ForestLiana::QueryHelper.get_one_association_names_string(@resource)
176
+ SchemaUtils.one_associations(@resource)
177
+ .select { |a| SchemaUtils.model_included?(a.klass) }
178
+ .map { |a| a.name.to_s }
174
179
  end
175
180
 
176
181
  def record_not_found
@@ -186,19 +191,6 @@ module ForestLiana
186
191
  is_sti_model? ? record.becomes(@resource) : record
187
192
  end
188
193
 
189
- def render_record_jsonapi record
190
- collection = ForestLiana::SchemaHelper.find_collection_from_model(@resource)
191
- collection_fields = collection.fields.map { |field| field[:field] }
192
- fields_to_serialize = {
193
- ForestLiana.name_for(@resource) => collection_fields.join(',')
194
- }
195
-
196
- serialize_model(get_record(record), {
197
- include: record_includes,
198
- fields: fields_to_serialize
199
- })
200
- end
201
-
202
194
  def render_jsonapi getter
203
195
  records = getter.records.map { |record| get_record(record) }
204
196
  fields_to_serialize = fields_per_model(params[:fields], @resource)
@@ -6,24 +6,14 @@ module ForestLiana
6
6
  before_action :find_resource, except: [:get_with_live_query]
7
7
  end
8
8
 
9
- CHART_TYPE_VALUE = 'Value';
10
- CHART_TYPE_PIE = 'Pie';
11
- CHART_TYPE_LINE = 'Line';
12
- CHART_TYPE_LEADERBOARD = 'Leaderboard';
13
- CHART_TYPE_OBJECTIVE = 'Objective';
14
-
15
9
  def get
16
- case params[:type]
17
- when CHART_TYPE_VALUE
10
+ case params[:type].try(:downcase)
11
+ when 'value'
18
12
  stat = ValueStatGetter.new(@resource, params)
19
- when CHART_TYPE_PIE
13
+ when 'pie'
20
14
  stat = PieStatGetter.new(@resource, params)
21
- when CHART_TYPE_LINE
15
+ when 'line'
22
16
  stat = LineStatGetter.new(@resource, params)
23
- when CHART_TYPE_OBJECTIVE
24
- stat = ObjectiveStatGetter.new(@resource, params)
25
- when CHART_TYPE_LEADERBOARD
26
- stat = LeaderboardStatGetter.new(@resource, params)
27
17
  end
28
18
 
29
19
  stat.perform
@@ -4,14 +4,68 @@ class ForestLiana::Model::Action
4
4
  include ActiveModel::Serialization
5
5
  extend ActiveModel::Naming
6
6
 
7
- # TODO: Remove :global option when we remove the deprecation warning.
8
- attr_accessor :id, :name, :endpoint, :http_method, :fields, :redirect,
9
- :global, :type, :download
7
+ attr_accessor :id, :name, :base_url, :endpoint, :http_method, :fields, :redirect,
8
+ :type, :download
10
9
 
11
10
  def initialize(attributes = {})
11
+ if attributes.key?(:global)
12
+ FOREST_LOGGER.error "REMOVED OPTION: The support for Smart Action \"global\" option is now " \
13
+ "removed. Please set \"type: 'global'\" instead of \"global: true\" for the " \
14
+ "\"#{attributes[:name]}\" Smart Action."
15
+ end
16
+
17
+
18
+ if attributes.key?(:type) && !['bulk', 'global', 'single'].include?(attributes[:type])
19
+ FOREST_LOGGER.warn "Please set a valid Smart Action type (\"bulk\", \"global\" or " \
20
+ "\"single\") for the \"#{attributes[:name]}\" Smart Action."
21
+ end
22
+
12
23
  attributes.each do |name, value|
13
24
  send("#{name}=", value)
14
25
  end
26
+
27
+ @fields ||= []
28
+
29
+ has_fields_without_name = false
30
+
31
+ @fields.delete_if do |field|
32
+ if field.key?(:field)
33
+ false
34
+ else
35
+ has_fields_without_name = true
36
+ true
37
+ end
38
+ end
39
+
40
+ @fields.map! do |field|
41
+ if field.key?(:isRequired)
42
+ FOREST_LOGGER.warn "DEPRECATION WARNING: isRequired on field \"#{field[:field]}\" is deprecated. Please use is_required."
43
+ field[:is_required] = !!field[:isRequired]
44
+ field.delete(:isRequired)
45
+ end
46
+
47
+ field[:type] = "String" unless field.key?(:type)
48
+ field[:default_value] = nil unless field.key?(:default_value)
49
+ field[:enums] = nil unless field.key?(:enums)
50
+ field[:is_required] = false unless field.key?(:is_required)
51
+ field[:reference] = nil unless field.key?(:reference)
52
+ field[:description] = nil unless field.key?(:description)
53
+ field[:widget] = nil unless field.key?(:widget)
54
+ field
55
+ end
56
+
57
+ if has_fields_without_name
58
+ FOREST_LOGGER.warn "Please set a name to all your \"#{@name}\" Smart Action fields " \
59
+ "(Smart Actions fields without name are ignored)."
60
+ end
61
+
62
+ dasherized_name = @name.downcase.gsub!(" ", "-") unless @name.nil?
63
+ @endpoint ||= "forest/actions/#{dasherized_name}" unless dasherized_name.nil?
64
+ @http_method ||= "POST"
65
+ @redirect ||= nil
66
+ @base_url ||= nil
67
+ @type ||= "bulk"
68
+ @download ||= false
15
69
  end
16
70
 
17
71
  def persisted?
@@ -5,21 +5,49 @@ class ForestLiana::Model::Collection
5
5
  extend ActiveModel::Naming
6
6
 
7
7
  attr_accessor :name, :fields, :actions, :segments, :only_for_relationships,
8
- :is_virtual, :is_read_only, :is_searchable, :display_name, :icon,
8
+ :is_virtual, :is_read_only, :is_searchable, :icon,
9
9
  :integration, :pagination_type, :search_fields,
10
10
  # TODO: Remove once lianas prior to 2.0.0 are not supported anymore.
11
11
  :name_old
12
12
 
13
13
  def initialize(attributes = {})
14
- @actions = []
15
- @segments = []
16
- @is_searchable = true
17
- @is_read_only = false
18
- @search_fields = nil
19
-
20
14
  attributes.each do |name, value|
21
15
  send("#{name}=", value)
22
16
  end
17
+
18
+ init_properties_with_default
19
+ end
20
+
21
+ def init_properties_with_default
22
+ @name_old ||= @name
23
+ @is_virtual ||= false
24
+ @icon ||= nil
25
+ @is_read_only ||= false
26
+ @is_searchable = true if @is_searchable.nil?
27
+ @only_for_relationships ||= false
28
+ @pagination_type ||= "page"
29
+ @search_fields ||= nil
30
+ @fields ||= []
31
+ @actions ||= []
32
+ @segments ||= []
33
+
34
+ @fields = @fields.map do |field|
35
+ field[:type] = "String" unless field.key?(:type)
36
+ field[:default_value] = nil unless field.key?(:default_value)
37
+ field[:enums] = nil unless field.key?(:enums)
38
+ field[:integration] = nil unless field.key?(:integration)
39
+ field[:is_filterable] = true unless field.key?(:is_filterable)
40
+ field[:is_read_only] = false unless field.key?(:is_read_only)
41
+ field[:is_required] = false unless field.key?(:is_required)
42
+ field[:is_sortable] = true unless field.key?(:is_sortable)
43
+ field[:is_virtual] = false unless field.key?(:is_virtual)
44
+ field[:reference] = nil unless field.key?(:reference)
45
+ field[:inverse_of] = nil unless field.key?(:inverse_of)
46
+ field[:relationship] = nil unless field.key?(:relationship)
47
+ field[:widget] = nil unless field.key?(:widget)
48
+ field[:validations] = nil unless field.key?(:validations)
49
+ field
50
+ end
23
51
  end
24
52
 
25
53
  def persisted?
@@ -32,13 +60,13 @@ class ForestLiana::Model::Collection
32
60
 
33
61
  def fields_smart_belongs_to
34
62
  fields.select do |field|
35
- field[:'is-virtual'] && field[:type] == 'String' && !field[:reference].nil?
63
+ field[:'is_virtual'] && field[:type] == 'String' && !field[:reference].nil?
36
64
  end
37
65
  end
38
66
 
39
67
  def string_smart_fields_names
40
68
  fields
41
- .select { |field| field[:'is-virtual'] && field[:type] == 'String' }
69
+ .select { |field| field[:'is_virtual'] && field[:type] == 'String' }
42
70
  .map { |field| field[:field].to_s }
43
71
  end
44
72
  end
@@ -10,7 +10,7 @@ class ForestLiana::Model::Segment
10
10
  attributes.each do |name, value|
11
11
  send("#{name}=", value)
12
12
  end
13
-
13
+
14
14
  @where = block if block
15
15
  end
16
16
 
@@ -0,0 +1,83 @@
1
+ class ForestLiana::SchemaSerializer
2
+ def initialize collections, meta
3
+ @collections = collections
4
+ @meta = meta
5
+ @data = []
6
+ @included = []
7
+ end
8
+
9
+ def serialize
10
+ populate_data_and_included
11
+ {
12
+ data: @data,
13
+ included: @included,
14
+ meta: @meta
15
+ }
16
+ end
17
+
18
+ private
19
+
20
+ def populate_data_and_included
21
+ @collections.each do |collection|
22
+ serialize_collection(collection)
23
+ end
24
+ end
25
+
26
+ def serialize_collection collection
27
+ collection_serialized = {
28
+ id: collection['name'],
29
+ type: 'collections',
30
+ attributes: {},
31
+ relationships: {
32
+ actions: {
33
+ data: []
34
+ },
35
+ segments: {
36
+ data: []
37
+ }
38
+ }
39
+ }
40
+
41
+ collection.each do |attribute, value|
42
+ if attribute == 'actions'
43
+ value.each do |action|
44
+ action_id = define_child_id(collection_serialized[:id], action['name'])
45
+ collection_serialized[:relationships][:actions][:data] << format_child_pointer('actions', action_id)
46
+ @included << format_child_content('actions', action_id, action)
47
+ end
48
+ elsif attribute == 'segments'
49
+ value.each do |segment|
50
+ segment_id = define_child_id(collection_serialized[:id], segment['name'])
51
+ collection_serialized[:relationships][:segments][:data] << format_child_pointer('segments', segment_id)
52
+ @included << format_child_content('segments', segment_id, segment)
53
+ end
54
+ else
55
+ collection_serialized[:attributes][attribute.to_sym] = value;
56
+ end
57
+ end
58
+
59
+ @data << collection_serialized
60
+ end
61
+
62
+ def define_child_id collection_id, object_id
63
+ "#{collection_id}.#{object_id}"
64
+ end
65
+
66
+ def format_child_pointer type, id
67
+ { id: id, type: type }
68
+ end
69
+
70
+ def format_child_content type, id, object
71
+ child_serialized = {
72
+ id: id,
73
+ type: type,
74
+ attributes: {}
75
+ }
76
+
77
+ object.each do |attribute, value|
78
+ child_serialized[:attributes][attribute.to_sym] = value;
79
+ end
80
+
81
+ child_serialized
82
+ end
83
+ end
@@ -35,12 +35,6 @@ module ForestLiana
35
35
  "ForestLiana::StripeBankAccountSerializer"
36
36
  elsif active_record_class == ForestLiana::Model::Stat
37
37
  "ForestLiana::StatSerializer"
38
- elsif active_record_class == ForestLiana::Model::Collection
39
- "ForestLiana::CollectionSerializer"
40
- elsif active_record_class == ForestLiana::Model::Action
41
- "ForestLiana::ActionSerializer"
42
- elsif active_record_class == ForestLiana::Model::Segment
43
- "ForestLiana::SegmentSerializer"
44
38
  elsif active_record_class == ForestLiana::MixpanelEvent
45
39
  "ForestLiana::MixpanelEventSerializer"
46
40
  else
@@ -179,27 +173,17 @@ module ForestLiana
179
173
 
180
174
  unless @is_smart_collection
181
175
  attributes(active_record_class).each do |attribute|
182
- serializer.attribute(attribute) do |x|
183
- begin
184
- object.send(attribute)
185
- rescue
186
- nil
187
- end
188
- end
176
+ serializer.attribute(attribute)
189
177
  end
190
178
 
191
179
  # NOTICE: Format time type fields during the serialization.
192
180
  attributes_time(active_record_class).each do |attribute|
193
181
  serializer.attribute(attribute) do |x|
194
- begin
195
- value = object.send(attribute)
196
- if value
197
- match = /(\d{2}:\d{2}:\d{2})/.match(value.to_s)
198
- (match && match[1]) ? match[1] : nil
199
- else
200
- nil
201
- end
202
- rescue
182
+ value = object.send(attribute)
183
+ if value
184
+ match = /(\d{2}:\d{2}:\d{2})/.match(value.to_s)
185
+ (match && match[1]) ? match[1] : nil
186
+ else
203
187
  nil
204
188
  end
205
189
  end
@@ -208,38 +192,22 @@ module ForestLiana
208
192
  # NOTICE: Format serialized fields.
209
193
  attributes_serialized(active_record_class).each do |attr, serialization|
210
194
  serializer.attribute(attr) do |x|
211
- begin
212
- value = object.send(attr)
213
- value ? value.to_json : nil
214
- rescue
215
- nil
216
- end
195
+ value = object.send(attr)
196
+ value ? value.to_json : nil
217
197
  end
218
198
  end
219
199
 
220
200
  # NOTICE: Format CarrierWave url attribute
221
201
  if active_record_class.respond_to?(:mount_uploader)
222
202
  active_record_class.uploaders.each do |key, value|
223
- serializer.attribute(key) do |x|
224
- begin
225
- object.send(key).try(:url)
226
- rescue
227
- nil
228
- end
229
- end
203
+ serializer.attribute(key) { |x| object.send(key).try(:url) }
230
204
  end
231
205
  end
232
206
 
233
207
  # NOTICE: Format Paperclip url attribute
234
208
  if active_record_class.respond_to?(:attachment_definitions)
235
209
  active_record_class.attachment_definitions.each do |key, value|
236
- serializer.attribute(key) do |x|
237
- begin
238
- object.send(key)
239
- rescue
240
- nil
241
- end
242
- end
210
+ serializer.attribute(key) { |x| object.send(key) }
243
211
  end
244
212
  end
245
213
 
@@ -249,11 +217,7 @@ module ForestLiana
249
217
  active_record_class.acts_as_taggable.respond_to?(:to_a)
250
218
  active_record_class.acts_as_taggable.to_a.each do |key, value|
251
219
  serializer.attribute(key) do |x|
252
- begin
253
- object.send(key).map(&:name)
254
- rescue
255
- nil
256
- end
220
+ object.send(key).map(&:name)
257
221
  end
258
222
  end
259
223
  end
@@ -307,7 +271,8 @@ module ForestLiana
307
271
  serializer.send(:has_many, :mixpanel_last_events) { }
308
272
  end
309
273
 
310
- ForestLiana::SerializerFactory.define_serializer(active_record_class, serializer)
274
+ ForestLiana::SerializerFactory.define_serializer(active_record_class,
275
+ serializer)
311
276
 
312
277
  serializer
313
278
  end