alba 2.0.1 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/benchmark/prep.rb ADDED
@@ -0,0 +1,82 @@
1
+ # --- Bundle dependencies ---
2
+
3
+ require "bundler/inline"
4
+
5
+ gemfile(true) do
6
+ source "https://rubygems.org"
7
+ git_source(:github) { |repo| "https://github.com/#{repo}.git" }
8
+
9
+ gem "active_model_serializers"
10
+ gem "activerecord", "6.1.3"
11
+ gem "alba", path: '../'
12
+ gem "benchmark-ips"
13
+ gem "benchmark-memory"
14
+ gem "blueprinter"
15
+ gem "fast_serializer_ruby"
16
+ gem "jbuilder"
17
+ gem 'turbostreamer'
18
+ gem "jserializer"
19
+ gem "multi_json"
20
+ gem "panko_serializer"
21
+ gem "pg"
22
+ gem "primalize"
23
+ gem "oj"
24
+ gem "representable"
25
+ gem "simple_ams"
26
+ gem "sqlite3"
27
+ end
28
+
29
+ # --- Test data model setup ---
30
+
31
+ require "pg"
32
+ require "active_record"
33
+ require "active_record/connection_adapters/postgresql_adapter"
34
+ require "logger"
35
+ require "oj"
36
+ require "sqlite3"
37
+ Oj.optimize_rails unless ENV['NO_OJ_OPTIMIZE_RAILS']
38
+
39
+ ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
40
+ # ActiveRecord::Base.logger = Logger.new($stdout)
41
+
42
+ ActiveRecord::Schema.define do
43
+ create_table :posts, force: true do |t|
44
+ t.string :body
45
+ end
46
+
47
+ create_table :comments, force: true do |t|
48
+ t.integer :post_id
49
+ t.string :body
50
+ t.integer :commenter_id
51
+ end
52
+
53
+ create_table :users, force: true do |t|
54
+ t.string :name
55
+ end
56
+ end
57
+
58
+ class Post < ActiveRecord::Base
59
+ has_many :comments
60
+ has_many :commenters, through: :comments, class_name: 'User', source: :commenter
61
+
62
+ def attributes
63
+ {id: nil, body: nil, commenter_names: commenter_names}
64
+ end
65
+
66
+ def commenter_names
67
+ commenters.pluck(:name)
68
+ end
69
+ end
70
+
71
+ class Comment < ActiveRecord::Base
72
+ belongs_to :post
73
+ belongs_to :commenter, class_name: 'User'
74
+
75
+ def attributes
76
+ {id: nil, body: nil}
77
+ end
78
+ end
79
+
80
+ class User < ActiveRecord::Base
81
+ has_many :comments
82
+ end
@@ -1,88 +1,7 @@
1
1
  # Benchmark script to run varieties of JSON serializers
2
2
  # Fetch Alba from local, otherwise fetch latest from RubyGems
3
3
 
4
- # --- Bundle dependencies ---
5
-
6
- require "bundler/inline"
7
-
8
- gemfile(true) do
9
- source "https://rubygems.org"
10
- git_source(:github) { |repo| "https://github.com/#{repo}.git" }
11
-
12
- gem "active_model_serializers"
13
- gem "activerecord", "6.1.3"
14
- gem "alba", path: '../'
15
- gem "benchmark-ips"
16
- gem "benchmark-memory"
17
- gem "blueprinter"
18
- gem "jbuilder"
19
- gem 'turbostreamer'
20
- gem "jserializer"
21
- gem "jsonapi-serializer" # successor of fast_jsonapi
22
- gem "multi_json"
23
- gem "panko_serializer"
24
- gem "pg"
25
- gem "primalize"
26
- gem "oj"
27
- gem "representable"
28
- gem "simple_ams"
29
- gem "sqlite3"
30
- end
31
-
32
- # --- Test data model setup ---
33
-
34
- require "pg"
35
- require "active_record"
36
- require "active_record/connection_adapters/postgresql_adapter"
37
- require "logger"
38
- require "oj"
39
- require "sqlite3"
40
- Oj.optimize_rails
41
-
42
- ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
43
- # ActiveRecord::Base.logger = Logger.new($stdout)
44
-
45
- ActiveRecord::Schema.define do
46
- create_table :posts, force: true do |t|
47
- t.string :body
48
- end
49
-
50
- create_table :comments, force: true do |t|
51
- t.integer :post_id
52
- t.string :body
53
- t.integer :commenter_id
54
- end
55
-
56
- create_table :users, force: true do |t|
57
- t.string :name
58
- end
59
- end
60
-
61
- class Post < ActiveRecord::Base
62
- has_many :comments
63
- has_many :commenters, through: :comments, class_name: 'User', source: :commenter
64
-
65
- def attributes
66
- {id: nil, body: nil, commenter_names: commenter_names}
67
- end
68
-
69
- def commenter_names
70
- commenters.pluck(:name)
71
- end
72
- end
73
-
74
- class Comment < ActiveRecord::Base
75
- belongs_to :post
76
- belongs_to :commenter, class_name: 'User'
77
-
78
- def attributes
79
- {id: nil, body: nil}
80
- end
81
- end
82
-
83
- class User < ActiveRecord::Base
84
- has_many :comments
85
- end
4
+ require_relative 'prep'
86
5
 
87
6
  # --- Alba serializers ---
88
7
 
@@ -177,70 +96,8 @@ class JserializerPostSerializer < Jserializer::Base
177
96
  end
178
97
  end
179
98
 
180
-
181
- # --- JSONAPI:Serializer serializers / (successor of fast_jsonapi) ---
182
-
183
- class JsonApiStandardCommentSerializer
184
- include JSONAPI::Serializer
185
-
186
- attribute :id
187
- attribute :body
188
- end
189
-
190
- class JsonApiStandardPostSerializer
191
- include JSONAPI::Serializer
192
-
193
- # set_type :post # optional
194
- attribute :id
195
- attribute :body
196
- attribute :commenter_names
197
-
198
- attribute :comments do |post|
199
- post.comments.map { |comment| JsonApiSameFormatCommentSerializer.new(comment) }
200
- end
201
- end
202
-
203
- # --- JSONAPI:Serializer serializers that format the code the same flat way as the other gems here ---
204
-
205
- # code to convert from JSON:API output to "flat" JSON, like the other serializers build
206
- class JsonApiSameFormatSerializer
207
- include JSONAPI::Serializer
208
-
209
- def as_json(*_options)
210
- hash = serializable_hash
211
-
212
- if hash[:data].is_a? Hash
213
- hash[:data][:attributes]
214
-
215
- elsif hash[:data].is_a? Array
216
- hash[:data].pluck(:attributes)
217
-
218
- elsif hash[:data].nil?
219
- { }
220
-
221
- else
222
- raise "unexpected data type #{hash[:data].class}"
223
- end
224
- end
225
- end
226
-
227
- class JsonApiSameFormatCommentSerializer < JsonApiSameFormatSerializer
228
- attribute :id
229
- attribute :body
230
- end
231
-
232
- class JsonApiSameFormatPostSerializer < JsonApiSameFormatSerializer
233
- attribute :id
234
- attribute :body
235
- attribute :commenter_names
236
-
237
- attribute :comments do |post|
238
- post.comments.map { |comment| JsonApiSameFormatCommentSerializer.new(comment) }
239
- end
240
- end
241
-
242
99
  # --- Panko serializers ---
243
- #
100
+
244
101
  require "panko_serializer"
245
102
 
246
103
  class PankoCommentSerializer < Panko::Serializer
@@ -259,7 +116,7 @@ class PankoPostSerializer < Panko::Serializer
259
116
  end
260
117
 
261
118
  # --- Primalize serializers ---
262
- #
119
+
263
120
  class PrimalizeCommentResource < Primalize::Single
264
121
  attributes id: integer, body: string
265
122
  end
@@ -376,8 +233,6 @@ ams = Proc.new { AMSPostSerializer.new(post, {}).to_json }
376
233
  blueprinter = Proc.new { PostBlueprint.render(post) }
377
234
  jbuilder = Proc.new { post.to_builder.target! }
378
235
  jserializer = Proc.new { JserializerPostSerializer.new(post).to_json }
379
- jsonapi = proc { JsonApiStandardPostSerializer.new(post).to_json }
380
- jsonapi_same_format = proc { JsonApiSameFormatPostSerializer.new(post).to_json }
381
236
  panko = proc { PankoPostSerializer.new.serialize_to_json(post) }
382
237
  primalize = proc { PrimalizePostResource.new(post).to_json }
383
238
  rails = Proc.new { ActiveSupport::JSON.encode(post.serializable_hash(include: :comments)) }
@@ -395,8 +250,6 @@ puts "Serializer outputs ----------------------------------"
395
250
  blueprinter: blueprinter,
396
251
  jbuilder: jbuilder, # different order
397
252
  jserializer: jserializer,
398
- jsonapi: jsonapi, # nested JSON:API format
399
- jsonapi_same_format: jsonapi_same_format,
400
253
  panko: panko,
401
254
  primalize: primalize,
402
255
  rails: rails,
@@ -417,8 +270,6 @@ Benchmark.ips do |x|
417
270
  x.report(:blueprinter, &blueprinter)
418
271
  x.report(:jbuilder, &jbuilder)
419
272
  x.report(:jserializer, &jserializer)
420
- x.report(:jsonapi, &jsonapi)
421
- x.report(:jsonapi_same_format, &jsonapi_same_format)
422
273
  x.report(:panko, &panko)
423
274
  x.report(:primalize, &primalize)
424
275
  x.report(:rails, &rails)
@@ -438,8 +289,6 @@ Benchmark.memory do |x|
438
289
  x.report(:blueprinter, &blueprinter)
439
290
  x.report(:jbuilder, &jbuilder)
440
291
  x.report(:jserializer, &jserializer)
441
- x.report(:jsonapi, &jsonapi)
442
- x.report(:jsonapi_same_format, &jsonapi_same_format)
443
292
  x.report(:panko, &panko)
444
293
  x.report(:primalize, &primalize)
445
294
  x.report(:rails, &rails)
@@ -12,7 +12,7 @@ This guide is aimed at helping ActiveModelSerializers users transition to Alba,
12
12
 
13
13
  ## Example class
14
14
 
15
- Example clsss is inherited `ActiveRecord::Base`, because [serializing PORO with AMS is pretty hard](https://github.com/rails-api/active_model_serializers/blob/0-10-stable/docs/howto/serialize_poro.md).
15
+ Example class is inherited `ActiveRecord::Base`, because [serializing PORO with AMS is pretty hard](https://github.com/rails-api/active_model_serializers/blob/0-10-stable/docs/howto/serialize_poro.md).
16
16
 
17
17
  ```rb
18
18
  class User < ActiveRecord::Base
@@ -175,7 +175,7 @@ class UserSerializer < ActiveModel::Serializer
175
175
  has_many :articles, serializer: ArticleSerializer # For has_many relation
176
176
  end
177
177
  user = User.create!
178
- user.craete_profile! email: email
178
+ user.create_profile! email: email
179
179
  user.articles.create! title: title, body: body
180
180
  ActiveModelSerializers::SerializableResource.new(
181
181
  user
data/docs/rails.md CHANGED
@@ -14,7 +14,7 @@ You might want to add some configurations to initializer file such as `alba.rb`
14
14
  ```ruby
15
15
  # alba.rb
16
16
  Alba.backend = :active_support
17
- Alba.enable_inference!(:active_support)
17
+ Alba.enable_inference!(with: :active_support)
18
18
  ```
19
19
 
20
20
  You can also use `:oj_rails` for backend if you prefer using Oj.
@@ -37,8 +37,10 @@ module Alba
37
37
  @object = @condition.call(object, params, target) if @condition
38
38
  return if @object.nil?
39
39
 
40
- if @resource.is_a?(Proc) && @object.is_a?(Enumerable)
41
- to_h_with_each_resource(within, params)
40
+ if @resource.is_a?(Proc)
41
+ return to_h_with_each_resource(within, params) if @object.is_a?(Enumerable)
42
+
43
+ @resource.call(@object).new(@object, within: within, params: params).to_h
42
44
  else
43
45
  to_h_with_constantize_resource(within, params)
44
46
  end
@@ -63,10 +65,10 @@ module Alba
63
65
  klass.transform_keys(key_transformation)
64
66
  klass.class_eval(&block)
65
67
  klass
66
- elsif Alba.inferring
68
+ elsif Alba.inflector
67
69
  Alba.infer_resource_class(@name, nesting: nesting)
68
70
  else
69
- raise ArgumentError, 'When Alba.inferring is false, either resource or block is required'
71
+ raise ArgumentError, 'When Alba.inflector is nil, either resource or block is required'
70
72
  end
71
73
  end
72
74
 
@@ -20,7 +20,7 @@ module Alba
20
20
  return Alba::REMOVE_KEY unless condition_passes?(resource, object)
21
21
 
22
22
  fetched_attribute = yield(@body)
23
- return fetched_attribute if fetched_attribute.nil? || !with_two_arity_proc_condition
23
+ return fetched_attribute if !with_two_arity_proc_condition
24
24
 
25
25
  return Alba::REMOVE_KEY unless resource.instance_exec(object, attribute_from_association_body_or(fetched_attribute), &@condition)
26
26
 
data/lib/alba/layout.rb CHANGED
@@ -8,8 +8,8 @@ module Alba
8
8
 
9
9
  def_delegators :@resource, :object, :params, :serializable_hash, :to_h
10
10
 
11
- # @params file [String] name of the layout file
12
- # @params inline [Proc] a proc returning JSON string or a Hash representing JSON
11
+ # @param file [String] name of the layout file
12
+ # @param inline [Proc] a proc returning JSON string or a Hash representing JSON
13
13
  def initialize(file:, inline:)
14
14
  if file
15
15
  raise ArgumentError, 'File layout must be a String representing filename' unless file.is_a?(String)
@@ -0,0 +1,8 @@
1
+ module Alba
2
+ # Rails integration
3
+ class Railtie < Rails::Railtie
4
+ initializer 'alba.initialize' do
5
+ Alba.inflector = :active_support
6
+ end
7
+ end
8
+ end
data/lib/alba/resource.rb CHANGED
@@ -11,7 +11,7 @@ module Alba
11
11
  module Resource
12
12
  # @!parse include InstanceMethods
13
13
  # @!parse extend ClassMethods
14
- DSLS = {_attributes: {}, _key: nil, _key_for_collection: nil, _meta: nil, _transform_type: :none, _transforming_root_key: false, _on_error: nil, _on_nil: nil, _layout: nil, _collection_key: nil}.freeze # rubocop:disable Layout/LineLength
14
+ DSLS = {_attributes: {}, _key: nil, _key_for_collection: nil, _meta: nil, _transform_type: :none, _transforming_root_key: false, _key_transformation_cascade: true, _on_error: nil, _on_nil: nil, _layout: nil, _collection_key: nil}.freeze # rubocop:disable Layout/LineLength
15
15
  private_constant :DSLS
16
16
 
17
17
  WITHIN_DEFAULT = Object.new.freeze
@@ -41,7 +41,6 @@ module Alba
41
41
  @object = object
42
42
  @params = params
43
43
  @within = within
44
- @method_existence = {} # Cache for `respond_to?` result
45
44
  DSLS.each_key { |name| instance_variable_set("@#{name}", self.class.__send__(name)) }
46
45
  end
47
46
 
@@ -79,7 +78,6 @@ module Alba
79
78
  #
80
79
  # @param root_key [Symbol, nil, true]
81
80
  # @param meta [Hash] metadata for this seialization
82
- # @param symbolize_root_key [Boolean] determines if root key should be symbolized
83
81
  # @return [Hash]
84
82
  def as_json(root_key: nil, meta: {})
85
83
  key = root_key.nil? ? fetch_key : root_key.to_s
@@ -149,7 +147,7 @@ module Alba
149
147
  end
150
148
 
151
149
  def _key_for_collection
152
- if Alba.inferring
150
+ if Alba.inflector
153
151
  @_key_for_collection == true ? resource_name(pluralized: true) : @_key_for_collection.to_s
154
152
  else
155
153
  @_key_for_collection == true ? raise_root_key_inference_error : @_key_for_collection.to_s
@@ -158,7 +156,7 @@ module Alba
158
156
 
159
157
  # @return [String]
160
158
  def _key
161
- if Alba.inferring
159
+ if Alba.inflector
162
160
  @_key == true ? resource_name(pluralized: false) : @_key.to_s
163
161
  else
164
162
  @_key == true ? raise_root_key_inference_error : @_key.to_s
@@ -174,7 +172,7 @@ module Alba
174
172
  end
175
173
 
176
174
  def raise_root_key_inference_error
177
- raise Alba::Error, 'You must call Alba.enable_inference! to set root_key to true for inferring root key.'
175
+ raise Alba::Error, 'You must set inflector when setting root key as true.'
178
176
  end
179
177
 
180
178
  def transforming_root_key?
@@ -182,27 +180,27 @@ module Alba
182
180
  end
183
181
 
184
182
  def converter
185
- lambda do |object|
186
- attributes_to_hash(object, {})
183
+ lambda do |obj|
184
+ attributes_to_hash(obj, {})
187
185
  end
188
186
  end
189
187
 
190
188
  def collection_converter
191
- lambda do |object, a|
189
+ lambda do |obj, a|
192
190
  a << {}
193
191
  h = a.last
194
- attributes_to_hash(object, h)
192
+ attributes_to_hash(obj, h)
195
193
  a
196
194
  end
197
195
  end
198
196
 
199
- def attributes_to_hash(object, hash)
197
+ def attributes_to_hash(obj, hash)
200
198
  attributes.each do |key, attribute|
201
- set_key_and_attribute_body_from(object, key, attribute, hash)
199
+ set_key_and_attribute_body_from(obj, key, attribute, hash)
202
200
  rescue ::Alba::Error, FrozenError, TypeError
203
201
  raise
204
202
  rescue StandardError => e
205
- handle_error(e, object, key, attribute, hash)
203
+ handle_error(e, obj, key, attribute, hash)
206
204
  end
207
205
  hash
208
206
  end
@@ -213,20 +211,28 @@ module Alba
213
211
  @_attributes
214
212
  end
215
213
 
216
- def set_key_and_attribute_body_from(object, key, attribute, hash)
214
+ # Default implementation for selecting attributes
215
+ # Override this method to filter attributes based on key and value
216
+ def select(_key, _value)
217
+ true
218
+ end
219
+
220
+ def set_key_and_attribute_body_from(obj, key, attribute, hash)
217
221
  key = transform_key(key)
218
- value = fetch_attribute(object, key, attribute)
222
+ value = fetch_attribute(obj, key, attribute)
223
+ return unless select(key, value)
224
+
219
225
  hash[key] = value unless value == Alba::REMOVE_KEY
220
226
  end
221
227
 
222
- def handle_error(error, object, key, attribute, hash)
228
+ def handle_error(error, obj, key, attribute, hash)
223
229
  on_error = @_on_error || :raise
224
230
  case on_error # rubocop:disable Style/MissingElse
225
231
  when :raise, nil then raise(error)
226
232
  when :nullify then hash[key] = nil
227
233
  when :ignore then nil
228
234
  when Proc
229
- key, value = on_error.call(error, object, key, attribute, self.class)
235
+ key, value = on_error.call(error, obj, key, attribute, self.class)
230
236
  hash[key] = value
231
237
  end
232
238
  end
@@ -237,7 +243,7 @@ module Alba
237
243
  return key if @_transform_type == :none || key.empty? # We can skip transformation
238
244
 
239
245
  inflector = Alba.inflector
240
- raise Alba::Error, 'Inflector is nil. You can set inflector with `Alba.enable_inference!(with: :active_support)` for example.' unless inflector
246
+ raise Alba::Error, 'Inflector is nil. You must set inflector before transforming keys.' unless inflector
241
247
 
242
248
  case @_transform_type # rubocop:disable Style/MissingElse
243
249
  when :camel then inflector.camelize(key)
@@ -247,23 +253,23 @@ module Alba
247
253
  end
248
254
  end
249
255
 
250
- def fetch_attribute(object, key, attribute) # rubocop:disable Metrics/CyclomaticComplexity
256
+ def fetch_attribute(obj, key, attribute) # rubocop:disable Metrics/CyclomaticComplexity
251
257
  value = case attribute
252
- when Symbol then fetch_attribute_from_object_and_resource(object, attribute)
253
- when Proc then instance_exec(object, &attribute)
254
- when Alba::Association then yield_if_within(attribute.name.to_sym) { |within| attribute.to_h(object, params: params, within: within) }
255
- when TypedAttribute, NestedAttribute then attribute.value(object)
256
- when ConditionalAttribute then attribute.with_passing_condition(resource: self, object: object) { |attr| fetch_attribute(object, key, attr) }
258
+ when Symbol then fetch_attribute_from_object_and_resource(obj, attribute)
259
+ when Proc then instance_exec(obj, &attribute)
260
+ when Alba::Association then yield_if_within(attribute.name.to_sym) { |within| attribute.to_h(obj, params: params, within: within) }
261
+ when TypedAttribute, NestedAttribute then attribute.value(obj)
262
+ when ConditionalAttribute then attribute.with_passing_condition(resource: self, object: obj) { |attr| fetch_attribute(obj, key, attr) }
257
263
  else
258
264
  raise ::Alba::Error, "Unsupported type of attribute: #{attribute.class}"
259
265
  end
260
- value.nil? && nil_handler ? instance_exec(object, key, attribute, &nil_handler) : value
266
+ value.nil? && nil_handler ? instance_exec(obj, key, attribute, &nil_handler) : value
261
267
  end
262
268
 
263
- def fetch_attribute_from_object_and_resource(object, attribute)
264
- has_method = @method_existence[attribute]
265
- has_method = @method_existence[attribute] = object.respond_to?(attribute) if has_method.nil?
266
- has_method ? object.__send__(attribute) : __send__(attribute, object)
269
+ def fetch_attribute_from_object_and_resource(obj, attribute)
270
+ obj.__send__(attribute)
271
+ rescue NoMethodError
272
+ __send__(attribute, obj)
267
273
  end
268
274
 
269
275
  def nil_handler
@@ -313,7 +319,7 @@ module Alba
313
319
  # @param attrs_with_types [Hash<[Symbol, String], [Array<Symbol, Proc>, Symbol]>]
314
320
  # attributes with name in its key and type and optional type converter in its value
315
321
  # @return [void]
316
- def attributes(*attrs, if: nil, **attrs_with_types) # rubocop:disable Naming/MethodParameterName
322
+ def attributes(*attrs, if: nil, **attrs_with_types)
317
323
  if_value = binding.local_variable_get(:if)
318
324
  assign_attributes(attrs, if_value)
319
325
  assign_attributes_with_types(attrs_with_types, if_value)
@@ -435,8 +441,8 @@ module Alba
435
441
 
436
442
  # Set layout
437
443
  #
438
- # @params file [String] name of the layout file
439
- # @params inline [Proc] a proc returning JSON string or a Hash representing JSON
444
+ # @param file [String] name of the layout file
445
+ # @param inline [Proc] a proc returning JSON string or a Hash representing JSON
440
446
  def layout(file: nil, inline: nil)
441
447
  @_layout = Layout.new(file: file, inline: inline)
442
448
  end
data/lib/alba/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Alba
2
- VERSION = '2.0.1'.freeze
2
+ VERSION = '2.2.0'.freeze
3
3
  end
data/lib/alba.rb CHANGED
@@ -4,13 +4,15 @@ require_relative 'alba/errors'
4
4
  require_relative 'alba/resource'
5
5
  require_relative 'alba/deprecation'
6
6
 
7
+ require_relative 'alba/railtie' if defined?(Rails::Railtie)
8
+
7
9
  # Core module
8
10
  module Alba
9
11
  class << self
10
- attr_reader :backend, :encoder, :inferring
12
+ attr_reader :backend, :encoder
11
13
 
12
- # Accessor for inflector, a module responsible for inflecting strings
13
- attr_accessor :inflector
14
+ # Getter for inflector, a module responsible for inflecting strings
15
+ attr_reader :inflector
14
16
 
15
17
  # Set the backend, which actually serializes object into JSON
16
18
  #
@@ -54,14 +56,36 @@ module Alba
54
56
  # @param with [Symbol, Class, Module] inflector
55
57
  # When it's a Symbol, it sets inflector with given name
56
58
  # When it's a Class or a Module, it sets given object to inflector
59
+ # @deprecated Use {#inflector=} instead
57
60
  def enable_inference!(with:)
61
+ Alba::Deprecation.warn('Alba.enable_inference! is deprecated. Use `Alba.inflector=` instead.')
58
62
  @inflector = inflector_from(with)
59
63
  @inferring = true
60
64
  end
61
65
 
62
66
  # Disable inference for key and resource name
67
+ #
68
+ # @deprecated Use {#inflector=} instead
63
69
  def disable_inference!
70
+ Alba::Deprecation.warn('Alba.disable_inference! is deprecated. Use `Alba.inflector = nil` instead.')
64
71
  @inferring = false
72
+ @inflector = nil
73
+ end
74
+
75
+ # @deprecated Use {#inflector} instead
76
+ # @return [Boolean] whether inference is enabled or not
77
+ def inferring
78
+ Alba::Deprecation.warn('Alba.inferring is deprecated. Use `Alba.inflector` instead.')
79
+ @inferring
80
+ end
81
+
82
+ # Set an inflector
83
+ #
84
+ # @param inflector [Symbol, Class, Module] inflector
85
+ # When it's a Symbol, it accepts `:default`, `:active_support` or `:dry`
86
+ # When it's a Class or a Module, it should have some methods, see {Alba::DefaultInflector}
87
+ def inflector=(inflector)
88
+ @inflector = inflector_from(inflector)
65
89
  end
66
90
 
67
91
  # @param block [Block] resource body
@@ -77,7 +101,7 @@ module Alba
77
101
  # @param nesting [String, nil] namespace Alba tries to find resource class in
78
102
  # @return [Class<Alba::Resource>] resource class
79
103
  def infer_resource_class(name, nesting: nil)
80
- raise Alba::Error, 'Inference is disabled so Alba cannot infer resource name. Use `Alba.enable_inference!` before use.' unless Alba.inferring
104
+ raise Alba::Error, 'Inference is disabled so Alba cannot infer resource name. Set inflector before use.' unless Alba.inflector
81
105
 
82
106
  const_parent = nesting.nil? ? Object : Object.const_get(nesting)
83
107
  const_parent.const_get("#{inflector.classify(name)}Resource")
@@ -95,6 +119,7 @@ module Alba
95
119
 
96
120
  def inflector_from(name_or_module)
97
121
  case name_or_module
122
+ when nil then nil
98
123
  when :default, :active_support
99
124
  require_relative 'alba/default_inflector'
100
125
  Alba::DefaultInflector
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: alba
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 2.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - OKURA Masafumi
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-11-02 00:00:00.000000000 Z
11
+ date: 2023-02-17 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Alba is the fastest JSON serializer for Ruby. It focuses on performance,
14
14
  flexibility and usability.
@@ -40,6 +40,7 @@ files:
40
40
  - alba.gemspec
41
41
  - benchmark/README.md
42
42
  - benchmark/collection.rb
43
+ - benchmark/prep.rb
43
44
  - benchmark/single_resource.rb
44
45
  - bin/console
45
46
  - bin/setup
@@ -58,6 +59,7 @@ files:
58
59
  - lib/alba/errors.rb
59
60
  - lib/alba/layout.rb
60
61
  - lib/alba/nested_attribute.rb
62
+ - lib/alba/railtie.rb
61
63
  - lib/alba/resource.rb
62
64
  - lib/alba/typed_attribute.rb
63
65
  - lib/alba/version.rb
@@ -82,14 +84,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
82
84
  requirements:
83
85
  - - ">="
84
86
  - !ruby/object:Gem::Version
85
- version: 2.6.0
87
+ version: 2.7.0
86
88
  required_rubygems_version: !ruby/object:Gem::Requirement
87
89
  requirements:
88
90
  - - ">="
89
91
  - !ruby/object:Gem::Version
90
92
  version: '0'
91
93
  requirements: []
92
- rubygems_version: 3.3.21
94
+ rubygems_version: 3.4.6
93
95
  signing_key:
94
96
  specification_version: 4
95
97
  summary: Alba is the fastest JSON serializer for Ruby.