alba 1.6.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,13 +1,15 @@
1
+ ![alba card](https://raw.githubusercontent.com/okuramasafumi/alba/main/logo/alba-card.png)
2
+ ----------
1
3
  [![Gem Version](https://badge.fury.io/rb/alba.svg)](https://badge.fury.io/rb/alba)
2
4
  [![CI](https://github.com/okuramasafumi/alba/actions/workflows/main.yml/badge.svg)](https://github.com/okuramasafumi/alba/actions/workflows/main.yml)
3
- [![codecov](https://codecov.io/gh/okuramasafumi/alba/branch/master/graph/badge.svg?token=3D3HEZ5OXT)](https://codecov.io/gh/okuramasafumi/alba)
5
+ [![codecov](https://codecov.io/gh/okuramasafumi/alba/branch/main/graph/badge.svg?token=3D3HEZ5OXT)](https://codecov.io/gh/okuramasafumi/alba)
4
6
  [![Maintainability](https://api.codeclimate.com/v1/badges/fdab4cc0de0b9addcfe8/maintainability)](https://codeclimate.com/github/okuramasafumi/alba/maintainability)
5
7
  ![GitHub code size in bytes](https://img.shields.io/github/languages/code-size/okuramasafumi/alba)
6
8
  ![GitHub](https://img.shields.io/github/license/okuramasafumi/alba)
7
9
 
8
10
  # Alba
9
11
 
10
- Alba is the fastest JSON serializer for Ruby, JRuby, and TruffleRuby.
12
+ Alba is a JSON serializer for Ruby, JRuby, and TruffleRuby.
11
13
 
12
14
  ## Discussions
13
15
 
@@ -17,21 +19,25 @@ If you've already used Alba, please consider posting your thoughts and feelings
17
19
 
18
20
  If you have feature requests or interesting ideas, join us with [Ideas](https://github.com/okuramasafumi/alba/discussions/categories/ideas). Let's make Alba even better, together!
19
21
 
22
+ ## Resources
23
+
24
+ If you want to know more about Alba, there's a [screencast](https://hanamimastery.com/episodes/21-serialization-with-alba) created by Sebastian from [Hanami Mastery](https://hanamimastery.com/). It covers basic features of Alba and how to use it in Hanami.
25
+
20
26
  ## Why Alba?
21
27
 
22
- Because it's fast, easy-to-use and extensible!
28
+ Because it's fast, easy and feature rich!
23
29
 
24
30
  ### Fast
25
31
 
26
- Alba is faster than most of the alternatives. We have a [benchmark](https://github.com/okuramasafumi/alba/tree/master/benchmark).
32
+ Alba is faster than most of the alternatives. We have a [benchmark](https://github.com/okuramasafumi/alba/tree/main/benchmark).
27
33
 
28
- ### Easy to use
34
+ ### Easy
29
35
 
30
- Alba provides four DSLs, `attributes` to fetch attribute with its name, `attribute` to execute block for the attribute, `one` to seriaize single attribute with another resource, and `many` to serialize collection attribute with another resource. When you want to do something complex, there are many examples in this README so you can mimic them to get started.
36
+ Alba is easy to use because there are only a few methods to remember. It's also easy to understand due to clean and short codebase. Finally it's easy to extend since it provides some methods for override to change default behavior of Alba.
31
37
 
32
- ### Extensible
38
+ ### Feature rich
33
39
 
34
- Alba embraces extensibility through common techniques such as class inheritance and module inclusion. Alba provides its capacity with one module so you can still have your own class hierarchy.
40
+ While Alba's core is simple, it provides additional features when you need them, For example, Alba provides [a way to control circular associations](#circular-associations-control), [inferring resource classes, root key and associations](#inference) and [supports layouts](#layout).
35
41
 
36
42
  ## Installation
37
43
 
@@ -81,9 +87,13 @@ Alba's configuration is fairly simple.
81
87
 
82
88
  Backend is the actual part serializing an object into JSON. Alba supports these backends.
83
89
 
84
- * Oj, the fastest. Gem installation required.
85
- * active_support, mostly for Rails. Gem installation required.
86
- * default or json, with no external dependencies.
90
+ |name|description|requires_external_gem|
91
+ |--|--|--|
92
+ |`oj`, `oj_strict`|Using Oj in `strict` mode|Yes(C extension)|
93
+ |`oj_rails`|It's `oj` but in `rails` mode|Yes(C extension)|
94
+ |`oj_default`|It's `oj` but respects mode set by users|Yes(C extension)|
95
+ |`active_support`|For Rails compatibility|Yes|
96
+ |`default`, `json`|Using `json` gem|No|
87
97
 
88
98
  You can set a backend like this:
89
99
 
@@ -177,8 +187,37 @@ UserResource.new([user1, user2]).serialize
177
187
  # => "{\"users\":[{\"id\":1,\"name\":\"Masafumi OKURA\",\"name_with_email\":\"Masafumi OKURA: masafumi@example.com\"},{\"id\":2,\"name\":\"Test User\",\"name_with_email\":\"Test User: test@example.com\"}]}"
178
188
  ```
179
189
 
190
+ If you have a simple case where you want to change only the name, you can use the Symbol to Proc shortcut:
191
+
192
+ ```ruby
193
+ class UserResource
194
+ include Alba::Resource
195
+
196
+ attribute :some_other_name, &:name
197
+ end
198
+ ```
199
+
200
+ #### Params
201
+
202
+ You can pass a Hash to the resource for internal use. It can be used as "flags" to control attribute content.
203
+
204
+ ```ruby
205
+ class UserResource
206
+ include Alba::Resource
207
+ attribute :name do |user|
208
+ params[:upcase] ? user.name.upcase : user.name
209
+ end
210
+ end
211
+
212
+ user = User.new(1, 'Masa', 'test@example.com')
213
+ UserResource.new(user).serialize # => "{\"name\":\"foo\"}"
214
+ UserResource.new(user, params: {upcase: true}).serialize # => "{\"name\":\"FOO\"}"
215
+ ```
216
+
180
217
  ### Serialization with associations
181
218
 
219
+ Associations can be defined using the `association` macro, which is also aliased as `one`, `many`, `has_one`, and `has_many` for convenience.
220
+
182
221
  ```ruby
183
222
  class User
184
223
  attr_reader :id, :created_at, :updated_at
@@ -255,17 +294,18 @@ class AnotherUserResource
255
294
  end
256
295
  ```
257
296
 
258
- You can "filter" association using second proc argument. This proc takes association object and `params`.
297
+ You can "filter" association using second proc argument. This proc takes association object, `params` and initial object.
259
298
 
260
299
  This feature is useful when you want to modify association, such as adding `includes` or `order` to ActiveRecord relations.
261
300
 
262
301
  ```ruby
263
302
  class User
264
- attr_reader :id
303
+ attr_reader :id, :banned
265
304
  attr_accessor :articles
266
305
 
267
- def initialize(id)
306
+ def initialize(id, banned = false)
268
307
  @id = id
308
+ @banned = banned
269
309
  @articles = []
270
310
  end
271
311
  end
@@ -293,9 +333,9 @@ class UserResource
293
333
 
294
334
  # Second proc works as a filter
295
335
  many :articles,
296
- proc { |articles, params|
336
+ proc { |articles, params, user|
297
337
  filter = params[:filter] || :odd?
298
- articles.select {|a| a.id.send(filter) }
338
+ articles.select {|a| a.id.send(filter) && !user.banned }
299
339
  },
300
340
  resource: ArticleResource
301
341
  end
@@ -312,6 +352,150 @@ UserResource.new(user, params: {filter: :even?}).serialize
312
352
  # => '{"id":1,"articles":[{"title":"Super nice"}]}'
313
353
  ```
314
354
 
355
+ You can change a key for association with `key` option.
356
+
357
+ ```ruby
358
+ class UserResource
359
+ include Alba::Resource
360
+
361
+ attributes :id
362
+
363
+ many :articles,
364
+ key: 'my_articles', # Set key here
365
+ resource: ArticleResource
366
+ end
367
+ UserResource.new(user).serialize
368
+ # => '{"id":1,"my_articles":[{"title":"Hello World!"}]}'
369
+ ```
370
+
371
+ You can omit resource option if you enable Alba's inference feature.
372
+
373
+ ```ruby
374
+ class UserResource
375
+ include Alba::Resource
376
+
377
+ attributes :id
378
+
379
+ many :articles # Using `ArticleResource`
380
+ end
381
+ UserResource.new(user).serialize
382
+ # => '{"id":1,"my_articles":[{"title":"Hello World!"}]}'
383
+ ```
384
+
385
+ If you need complex logic to determine what resource to use for association, you can use a Proc for resource option.
386
+
387
+ ```ruby
388
+ class UserResource
389
+ include Alba::Resource
390
+
391
+ attributes :id
392
+
393
+ many :articles, ->(article) { article.with_comment? ? ArticleWithCommentResource : ArticleResource }
394
+ end
395
+ ```
396
+
397
+ Note that using a Proc slows down serialization if there are too `many` associated objects.
398
+
399
+ #### Params override
400
+
401
+ Associations can override params. This is useful when associations are deeply nested.
402
+
403
+ ```ruby
404
+ class BazResource
405
+ include Alba::Resource
406
+
407
+ attributes :data
408
+ attributes :secret, if: proc { params[:expose_secret] }
409
+ end
410
+
411
+ class BarResource
412
+ include Alba::Resource
413
+
414
+ one :baz, resource: BazResource
415
+ end
416
+
417
+ class FooResource
418
+ include Alba::Resource
419
+
420
+ root_key :foo
421
+
422
+ one :bar, resource: BarResource
423
+ end
424
+
425
+ class FooResourceWithParamsOverride
426
+ include Alba::Resource
427
+
428
+ root_key :foo
429
+
430
+ one :bar, resource: BarResource, params: { expose_secret: false }
431
+ end
432
+
433
+ Baz = Struct.new(:data, :secret)
434
+ Bar = Struct.new(:baz)
435
+ Foo = Struct.new(:bar)
436
+
437
+ foo = Foo.new(Bar.new(Baz.new(1, 'secret')))
438
+ FooResource.new(foo, params: {expose_secret: true}).serialize # => '{"foo":{"bar":{"baz":{"data":1,"secret":"secret"}}}}'
439
+ FooResourceWithParamsOverride.new(foo, params: {expose_secret: true}).serialize # => '{"foo":{"bar":{"baz":{"data":1}}}}'
440
+ ```
441
+
442
+ ### Nested Attribute
443
+
444
+ Alba supports nested attributes that makes it easy to build complex data structure from single object.
445
+
446
+ In order to define nested attributes, you can use `nested` or `nested_attribute` (alias of `nested`).
447
+
448
+ ```ruby
449
+ class User
450
+ attr_accessor :id, :name, :email, :city, :zipcode
451
+
452
+ def initialize(id, name, email, city, zipcode)
453
+ @id = id
454
+ @name = name
455
+ @email = email
456
+ @city = city
457
+ @zipcode = zipcode
458
+ end
459
+ end
460
+
461
+ class UserResource
462
+ include Alba::Resource
463
+
464
+ root_key :user
465
+
466
+ attributes :id
467
+
468
+ nested_attribute :address do
469
+ attributes :city, :zipcode
470
+ end
471
+ end
472
+
473
+ user = User.new(1, 'Masafumi OKURA', 'masafumi@example.com', 'Tokyo', '0000000')
474
+ UserResource.new(user).serialize
475
+ # => '{"user":{"id":1,"address":{"city":"Tokyo","zipcode":"0000000"}}}'
476
+ ```
477
+
478
+ Nested attributes can be nested deeply.
479
+
480
+ ```ruby
481
+ class FooResource
482
+ include Alba::Resource
483
+
484
+ root_key :foo
485
+
486
+ nested :bar do
487
+ nested :baz do
488
+ attribute :deep do
489
+ 42
490
+ end
491
+ end
492
+ end
493
+ end
494
+
495
+ FooResource.new(nil).serialize
496
+ # => '{"foo":{"bar":{"baz":{"deep":42}}}}'
497
+ ```
498
+
315
499
  ### Inline definition with `Alba.serialize`
316
500
 
317
501
  `Alba.serialize` method is a shortcut to define everything inline.
@@ -335,7 +519,57 @@ Alba.serialize(something)
335
519
 
336
520
  Although this might be useful sometimes, it's generally recommended to define a class for Resource.
337
521
 
338
- ### Inheritance and attributes filter
522
+ ### Serializable Hash
523
+
524
+ Instead of serializing to JSON, you can also output a Hash by calling `serializable_hash` or the `to_h` alias. Note also that the `serialize` method is aliased as `to_json`.
525
+
526
+ ```ruby
527
+ # These are equivalent and will return serialized JSON
528
+ UserResource.new(user).serialize
529
+ UserResource.new(user).to_json
530
+
531
+ # These are equivalent and will return a Hash
532
+ UserResource.new(user).serializable_hash
533
+ UserResource.new(user).to_h
534
+ ```
535
+
536
+ If you want a Hash that corresponds to a JSON String returned by `serialize` method, you can use `as_json`.
537
+
538
+ ```ruby
539
+ # These are equivalent and will return the same result
540
+ UserResource.new(user).serialize
541
+ UserResource.new(user).to_json
542
+ JSON.generate(UserResource.new(user).as_json)
543
+ ```
544
+
545
+ ### Inheritance
546
+
547
+ When you include `Alba::Resource` in your class, it's just a class so you can define any class that inherits from it. You can add new attributes to inherited class like below:
548
+
549
+ ```ruby
550
+ class FooResource
551
+ include Alba::Resource
552
+
553
+ root_key :foo
554
+
555
+ attributes :bar
556
+ end
557
+
558
+ class ExtendedFooResource < FooResource
559
+ root_key :foofoo
560
+
561
+ attributes :baz
562
+ end
563
+
564
+ Foo = Struct.new(:bar, :baz)
565
+ foo = Foo.new(1, 2)
566
+ FooResource.new(foo).serialize # => '{"foo":{"bar":1}}'
567
+ ExtendedFooResource.new(foo).serialize # => '{"foo":{"bar":1,"baz":2}}'
568
+ ```
569
+
570
+ In this example we add `baz` attribute and change `root_key`. This way, you can extend existing resource classes just like normal OOP. Don't forget that when your inheritance structure is too deep it'll become difficult to modify existing classes.
571
+
572
+ ### Filtering attributes
339
573
 
340
574
  You can filter out certain attributes by overriding `attributes` instance method. This is useful when you want to customize existing resource with inheritance.
341
575
 
@@ -408,6 +642,8 @@ Possible values for `transform_keys` argument are:
408
642
  * `:snake` for snake_case
409
643
  * `:none` for not transforming keys
410
644
 
645
+ #### Root key transformation
646
+
411
647
  You can also transform root key when:
412
648
 
413
649
  * `Alba.enable_inference!` is called
@@ -441,74 +677,81 @@ BankAccountResource.new(bank_account).serialize
441
677
 
442
678
  This behavior to transform root key will become default at version 2.
443
679
 
444
- Supported transformation types are :camel, :lower_camel and :dash.
680
+ #### Key transformation cascading
445
681
 
446
- #### Custom inflector
682
+ When you use `transform_keys` with inline association, it automatically applies the same transformation type to those inline association.
447
683
 
448
- A custom inflector can be plugged in as follows.
684
+ This is the default behavior from version 2, but you can do the same thing with adding `transform_keys` to each association.
685
+
686
+ You can also turn it off by setting `cascade: false` option to `transform_keys`.
449
687
 
450
688
  ```ruby
451
- module CustomInflector
452
- module_function
689
+ class User
690
+ attr_reader :id, :first_name, :last_name
453
691
 
454
- def camelize(string)
692
+ def initialize(id, first_name, last_name)
693
+ @id = id
694
+ @first_name = first_name
695
+ @last_name = last_name
696
+ @bank_account = BankAccount.new(1234)
455
697
  end
698
+ end
456
699
 
457
- def camelize_lower(string)
458
- end
700
+ class BankAccount
701
+ attr_reader :account_number
459
702
 
460
- def dasherize(string)
703
+ def initialize(account_number)
704
+ @account_number = account_number
461
705
  end
706
+ end
462
707
 
463
- def underscore(string)
464
- end
708
+ class UserResource
709
+ include Alba::Resource
465
710
 
466
- def classify(string)
711
+ attributes :id, :first_name, :last_name
712
+
713
+ transform_keys :lower_camel # Default is cascade: true
714
+
715
+ one :bank_account do
716
+ attributes :account_number
467
717
  end
468
718
  end
469
719
 
470
- Alba.enable_inference!(with: CustomInflector)
720
+ user = User.new(1, 'Masafumi', 'Okura')
721
+ UserResource.new(user).serialize
722
+ # => '{"id":1,"firstName":"Masafumi","lastName":"Okura","bankAccount":{"accountNumber":1234}}'
471
723
  ```
472
724
 
473
- ### Filtering attributes
725
+ #### Custom inflector
474
726
 
475
- You can filter attributes by overriding `Alba::Resource#converter` method, but it's a bit tricky.
727
+ A custom inflector can be plugged in as follows.
476
728
 
477
729
  ```ruby
478
- class User
479
- attr_accessor :id, :name, :email, :created_at, :updated_at
730
+ module CustomInflector
731
+ module_function
480
732
 
481
- def initialize(id, name, email)
482
- @id = id
483
- @name = name
484
- @email = email
733
+ def camelize(string)
485
734
  end
486
- end
487
735
 
488
- class UserResource
489
- include Alba::Resource
736
+ def camelize_lower(string)
737
+ end
490
738
 
491
- attributes :id, :name, :email
739
+ def dasherize(string)
740
+ end
492
741
 
493
- private
742
+ def underscore(string)
743
+ end
494
744
 
495
- # Here using `Proc#>>` method to compose a proc from `super`
496
- def converter
497
- super >> proc { |hash| hash.compact }
745
+ def classify(string)
498
746
  end
499
747
  end
500
748
 
501
- user = User.new(1, nil, nil)
502
- UserResource.new(user).serialize # => '{"id":1}'
749
+ Alba.enable_inference!(with: CustomInflector)
503
750
  ```
504
751
 
505
- The key part is the use of `Proc#>>` since `Alba::Resource#converter` returns a `Proc` which contains the basic logic and it's impossible to change its behavior by just overriding the method.
506
-
507
- It's not recommended to swap the whole conversion logic. It's recommended to always call `super` when you override `converter`.
508
-
509
752
  ### Conditional attributes
510
753
 
511
- Filtering attributes with overriding `convert` works well for simple cases. However, It's cumbersome when we want to filter various attributes based on different conditions for keys.
754
+ Filtering attributes with overriding `attributes` works well for simple cases. However, It's cumbersome when we want to filter various attributes based on different conditions for keys.
512
755
 
513
756
  In these cases, conditional attributes works well. We can pass `if` option to `attributes`, `attribute`, `one` and `many`. Below is an example for the same effect as [filtering attributes section](#filtering-attributes).
514
757
 
@@ -761,7 +1004,7 @@ Note that setting root key is required when setting a metadata.
761
1004
 
762
1005
  You can control circular associations with `within` option. `within` option is a nested Hash such as `{book: {authors: books}}`. In this example, Alba serializes a book's authors' books. This means you can reference `BookResource` from `AuthorResource` and vice versa. This is really powerful when you have a complex data structure and serialize certain parts of it.
763
1006
 
764
- For more details, please refer to [test code](https://github.com/okuramasafumi/alba/blob/master/test/usecases/circular_association_test.rb)
1007
+ For more details, please refer to [test code](https://github.com/okuramasafumi/alba/blob/main/test/usecases/circular_association_test.rb)
765
1008
 
766
1009
  ### Experimental support of types
767
1010
 
@@ -804,6 +1047,37 @@ UserResource.new(user).serialize
804
1047
 
805
1048
  Note that this feature is experimental and interfaces are subject to change.
806
1049
 
1050
+ ### Collection serialization into Hash
1051
+
1052
+ Sometimes we want to serialize a collection into a Hash, not an Array. It's possible with Alba.
1053
+
1054
+ ```ruby
1055
+ class User
1056
+ attr_reader :id, :name
1057
+ def initialize(id, name)
1058
+ @id, @name = id, name
1059
+ end
1060
+ end
1061
+
1062
+ class UserResource
1063
+ include Alba::Resource
1064
+
1065
+ collection_key :id # This line is important
1066
+
1067
+ attributes :id, :name
1068
+ end
1069
+
1070
+ user1 = User.new(1, 'John')
1071
+ user2 = User.new(2, 'Masafumi')
1072
+
1073
+ UserResource.new([user1, user2]).serialize
1074
+ # => '{"1":{"id":1,"name":"John"},"2":{"id":2,"name":"Masafumi"}}'
1075
+ ```
1076
+
1077
+ In the snippet above, `collection_key :id` specifies the key used for the key of the collection hash. In this example it's `:id`.
1078
+
1079
+ Make sure that collection key is unique for the collection.
1080
+
807
1081
  ### Layout
808
1082
 
809
1083
  Sometimes we'd like to serialize JSON into a template. In other words, we need some structure OUTSIDE OF serialized JSON. IN HTML world, we call it a "layout".
@@ -972,6 +1246,54 @@ end
972
1246
 
973
1247
  In this way we have shorter and cleaner code. Note that we need to use `send` or `public_send` in `attribute` block to get attribute data.
974
1248
 
1249
+ ### Debugging
1250
+
1251
+ Debugging is not easy. If you find Alba not working as you expect, there are a few things to do:
1252
+
1253
+ 1. Inspect
1254
+
1255
+ The typical code looks like this:
1256
+
1257
+ ```ruby
1258
+ class FooResource
1259
+ include Alba::Resource
1260
+ attributes :id
1261
+ end
1262
+ FooResource.new(foo).serialize
1263
+ ```
1264
+
1265
+ Notice that we instantiate `FooResource` and then call `serialize` method. We can get various information by calling `inspect` method on it.
1266
+
1267
+ ```ruby
1268
+ puts FooResource.new(foo).inspect # or: p class FooResource.new(foo)
1269
+ # => "#<FooResource:0x000000010e21f408 @object=[#<Foo:0x000000010e3470d8 @id=1>], @params={}, @within=#<Object:0x000000010df2eac8>, @method_existence={}, @_attributes={:id=>:id}, @_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>"
1270
+ ```
1271
+
1272
+ The output might be different depending on the version of Alba or the object you give, but the concepts are the same. `@object` represents the object you gave as an argument to `new` method, `@_attributes` represents the attributes you defined in `FooResource` class using `attributes` DSL.
1273
+
1274
+ Other things are not so important, but you need to take care of corresponding part when you use additional features such as `root_key`, `transform_keys` and adding params.
1275
+
1276
+ 2. Logging
1277
+
1278
+ Alba currently doesn't support logging directly, but you can add your own logging module to Alba easily.
1279
+
1280
+ ```ruby
1281
+ module Logging
1282
+ def serialize(...) # `...` was added in Ruby 2.7
1283
+ puts serializable_hash
1284
+ super(...)
1285
+ end
1286
+ end
1287
+
1288
+ FooResource.prepend Logging
1289
+ FooResource.new(foo).serialize
1290
+ # => "{:id=>1}" is printed
1291
+ ```
1292
+
1293
+ Here, we override `serialize` method with `prepend`. In overridden method we print the result of `serializable_hash` that gives the basic hash for serialization to `serialize` method. Using `...` allows us to override without knowing method signiture of `serialize`.
1294
+
1295
+ Don't forget calling `super` in this way.
1296
+
975
1297
  ## Rails
976
1298
 
977
1299
  When you use Alba in Rails, you can create an initializer file with the line below for compatibility with Rails JSON encoder.
@@ -982,6 +1304,8 @@ Alba.backend = :active_support
982
1304
  Alba.backend = :oj_rails
983
1305
  ```
984
1306
 
1307
+ To find out more details, please see https://github.com/okuramasafumi/alba/blob/main/docs/rails.md
1308
+
985
1309
  ## Why named "Alba"?
986
1310
 
987
1311
  The name "Alba" comes from "albatross", a kind of birds. In Japanese, this bird is called "Aho-dori", which means "stupid bird". I find it funny because in fact albatrosses fly really fast. I hope Alba looks stupid but in fact it does its job quick.
@@ -995,14 +1319,13 @@ There are great pioneers in Ruby's ecosystem which does basically the same thing
995
1319
 
996
1320
  ## Development
997
1321
 
998
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
1322
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `bundle exec rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
999
1323
 
1000
1324
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
1001
1325
 
1002
1326
  ## Contributing
1003
1327
 
1004
- Bug reports and pull requests are welcome on GitHub at https://github.com/okuramasafumi/alba. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/okuramasafumi/alba/blob/master/CODE_OF_CONDUCT.md).
1005
-
1328
+ Thank you for begin interested in contributing to Alba! Please see [contributors guide](https://github.com/okuramasafumi/alba/blob/main/CONTRIBUTING.md) before start contributing. If you have any questions, please feel free to ask in [Discussions](https://github.com/okuramasafumi/alba/discussions).
1006
1329
 
1007
1330
  ## License
1008
1331
 
@@ -1010,4 +1333,4 @@ The gem is available as open source under the terms of the [MIT License](https:/
1010
1333
 
1011
1334
  ## Code of Conduct
1012
1335
 
1013
- Everyone interacting in the Alba project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/okuramasafumi/alba/blob/master/CODE_OF_CONDUCT.md).
1336
+ Everyone interacting in the Alba project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/okuramasafumi/alba/blob/main/CODE_OF_CONDUCT.md).
data/Rakefile CHANGED
@@ -1,12 +1,12 @@
1
1
  require "bundler/gem_tasks"
2
2
  require "rake/testtask"
3
3
 
4
- ENV["BUNDLE_GEMFILE"] = File.expand_path("gemfiles/all.gemfile") if ENV["BUNDLE_GEMFILE"] == File.expand_path("Gemfile") || ENV["BUNDLE_GEMFILE"].empty? || ENV["BUNDLE_GEMFILE"].nil?
4
+ ENV["BUNDLE_GEMFILE"] = File.expand_path("Gemfile") if ENV["BUNDLE_GEMFILE"] == File.expand_path("Gemfile") || ENV["BUNDLE_GEMFILE"].empty? || ENV["BUNDLE_GEMFILE"].nil?
5
5
 
6
6
  Rake::TestTask.new(:test) do |t|
7
7
  t.libs << "test"
8
8
  t.libs << "lib"
9
- file_list = ENV["BUNDLE_GEMFILE"] == File.expand_path("gemfiles/all.gemfile") ? FileList["test/**/*_test.rb"] : FileList["test/dependencies/test_dependencies.rb"]
9
+ file_list = ENV["BUNDLE_GEMFILE"] == File.expand_path("Gemfile") ? FileList["test/**/*_test.rb"] : FileList["test/dependencies/test_dependencies.rb"]
10
10
  t.test_files = file_list
11
11
  end
12
12
 
data/alba.gemspec CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
10
10
  spec.description = "Alba is the fastest JSON serializer for Ruby. It focuses on performance, flexibility and usability."
11
11
  spec.homepage = 'https://github.com/okuramasafumi/alba'
12
12
  spec.license = 'MIT'
13
- spec.required_ruby_version = Gem::Requirement.new('>= 2.5.0')
13
+ spec.required_ruby_version = Gem::Requirement.new('>= 2.6.0')
14
14
 
15
15
  spec.metadata = {
16
16
  'bug_tracker_uri' => 'https://github.com/okuramasafumi/issues',