alba 3.6.0 → 3.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/CHANGELOG.md +6 -0
 - data/README.md +91 -1
 - data/lib/alba/resource.rb +32 -3
 - data/lib/alba/version.rb +1 -1
 - metadata +3 -3
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 14523f0f31f5993205b02095c3e6a8115ef83728961cf720dde4d9599be3168a
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 9a2de9344c9b7bf95daa07e0d61339a08285f0cdadf9b694b58f73e7b0773970
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: e7f8062cca1bbccbe4d4e871fd5ad2ab42a5b25acc0d2b9edd3e8247af021edaca981988eeb8428675c8bdc8bcbc14fa5ee45d90d524ca76987ab469fc2a6203
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: ea0cd1598c2ef8f76e740309ff925b8c26ef60bef6174755b23549d3fd9a98aefeab26bb6d47b73c92c9b92d84125717b157369f25ba2d3631532bec522a9765
         
     | 
    
        data/CHANGELOG.md
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | 
         @@ -122,7 +122,7 @@ Alba supports CRuby 3.0 and higher and latest JRuby and TruffleRuby. 
     | 
|
| 
       122 
122 
     | 
    
         | 
| 
       123 
123 
     | 
    
         
             
            ## Documentation
         
     | 
| 
       124 
124 
     | 
    
         | 
| 
       125 
     | 
    
         
            -
            You can find the documentation on [ 
     | 
| 
      
 125 
     | 
    
         
            +
            You can find the documentation on [GitHub Pages](https://okuramasafumi.github.io/alba/).
         
     | 
| 
       126 
126 
     | 
    
         | 
| 
       127 
127 
     | 
    
         
             
            ## Features
         
     | 
| 
       128 
128 
     | 
    
         | 
| 
         @@ -1073,6 +1073,40 @@ class UserResource2 
     | 
|
| 
       1073 
1073 
     | 
    
         
             
            end
         
     | 
| 
       1074 
1074 
     | 
    
         
             
            ```
         
     | 
| 
       1075 
1075 
     | 
    
         | 
| 
      
 1076 
     | 
    
         
            +
            ### Traits
         
     | 
| 
      
 1077 
     | 
    
         
            +
             
     | 
| 
      
 1078 
     | 
    
         
            +
            Traits is an easy way to a group of attributes and apply it to the resource.
         
     | 
| 
      
 1079 
     | 
    
         
            +
             
     | 
| 
      
 1080 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 1081 
     | 
    
         
            +
            class User
         
     | 
| 
      
 1082 
     | 
    
         
            +
              attr_accessor :id, :name, :email
         
     | 
| 
      
 1083 
     | 
    
         
            +
             
     | 
| 
      
 1084 
     | 
    
         
            +
              def initialize(id, name, email)
         
     | 
| 
      
 1085 
     | 
    
         
            +
                @id = id
         
     | 
| 
      
 1086 
     | 
    
         
            +
                @name = name
         
     | 
| 
      
 1087 
     | 
    
         
            +
                @email = email
         
     | 
| 
      
 1088 
     | 
    
         
            +
              end
         
     | 
| 
      
 1089 
     | 
    
         
            +
            end
         
     | 
| 
      
 1090 
     | 
    
         
            +
             
     | 
| 
      
 1091 
     | 
    
         
            +
            class UserResource
         
     | 
| 
      
 1092 
     | 
    
         
            +
              include Alba::Resource
         
     | 
| 
      
 1093 
     | 
    
         
            +
             
     | 
| 
      
 1094 
     | 
    
         
            +
              attributes :id
         
     | 
| 
      
 1095 
     | 
    
         
            +
             
     | 
| 
      
 1096 
     | 
    
         
            +
              trait :additional do
         
     | 
| 
      
 1097 
     | 
    
         
            +
                attributes :name, :email
         
     | 
| 
      
 1098 
     | 
    
         
            +
              end
         
     | 
| 
      
 1099 
     | 
    
         
            +
            end
         
     | 
| 
      
 1100 
     | 
    
         
            +
             
     | 
| 
      
 1101 
     | 
    
         
            +
            user = User.new(1, 'Foo', 'foo@example.org')
         
     | 
| 
      
 1102 
     | 
    
         
            +
            UserResource.new(user).serialize # => '{"id":1}'
         
     | 
| 
      
 1103 
     | 
    
         
            +
            UserResource.new(user, with_traits: :additional).serialize # => '{"id":1,"name":"Foo","email":"foo@example.com"}'
         
     | 
| 
      
 1104 
     | 
    
         
            +
            ```
         
     | 
| 
      
 1105 
     | 
    
         
            +
             
     | 
| 
      
 1106 
     | 
    
         
            +
            This way, we can keep the resource class simple and inject conditions from outside. We can get the same result with the combination of `if` and `params`, but using `traits` DSL can make the resource class readable.
         
     | 
| 
      
 1107 
     | 
    
         
            +
             
     | 
| 
      
 1108 
     | 
    
         
            +
            We can specify multiple traits at once with `with_traits: []` keyword argument.
         
     | 
| 
      
 1109 
     | 
    
         
            +
             
     | 
| 
       1076 
1110 
     | 
    
         
             
            ### Default
         
     | 
| 
       1077 
1111 
     | 
    
         | 
| 
       1078 
1112 
     | 
    
         
             
            Alba doesn't support default value for attributes, but it's easy to set a default value.
         
     | 
| 
         @@ -1807,6 +1841,58 @@ Here, we override `serialize` method with `prepend`. In overridden method we pri 
     | 
|
| 
       1807 
1841 
     | 
    
         | 
| 
       1808 
1842 
     | 
    
         
             
            Don't forget calling `super` in this way.
         
     | 
| 
       1809 
1843 
     | 
    
         | 
| 
      
 1844 
     | 
    
         
            +
            ## Tips and Tricks
         
     | 
| 
      
 1845 
     | 
    
         
            +
             
     | 
| 
      
 1846 
     | 
    
         
            +
            ### Treating specific classes as non-collection
         
     | 
| 
      
 1847 
     | 
    
         
            +
             
     | 
| 
      
 1848 
     | 
    
         
            +
            Sometimes we need to serialize an object that's `Enumerable` but not a collection. By default, Alba treats `Hash`, `Range` and `Struct` as non-collection object, but if we want to add some classes to this list, we can override `Alba.collection?` method like following:
         
     | 
| 
      
 1849 
     | 
    
         
            +
             
     | 
| 
      
 1850 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 1851 
     | 
    
         
            +
            Alba.singleton_class.prepend(
         
     | 
| 
      
 1852 
     | 
    
         
            +
              Module.new do
         
     | 
| 
      
 1853 
     | 
    
         
            +
                def collection?(object)
         
     | 
| 
      
 1854 
     | 
    
         
            +
                  super && !object.is_a?(SomeClass)
         
     | 
| 
      
 1855 
     | 
    
         
            +
                end
         
     | 
| 
      
 1856 
     | 
    
         
            +
              end
         
     | 
| 
      
 1857 
     | 
    
         
            +
            )
         
     | 
| 
      
 1858 
     | 
    
         
            +
            ```
         
     | 
| 
      
 1859 
     | 
    
         
            +
             
     | 
| 
      
 1860 
     | 
    
         
            +
            ### Adding indexes to `many` association
         
     | 
| 
      
 1861 
     | 
    
         
            +
             
     | 
| 
      
 1862 
     | 
    
         
            +
            Let's say an author has many books. We want returned JSON to include indexes of each book. In this case, we can reduce the number of executed SQL by fetching indexes ahead and push indexes into `param`.
         
     | 
| 
      
 1863 
     | 
    
         
            +
             
     | 
| 
      
 1864 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 1865 
     | 
    
         
            +
            Author = Data.define(:id, :books)
         
     | 
| 
      
 1866 
     | 
    
         
            +
            Book = Data.define(:id, :name)
         
     | 
| 
      
 1867 
     | 
    
         
            +
             
     | 
| 
      
 1868 
     | 
    
         
            +
            book1 = Book.new(1, 'book1')
         
     | 
| 
      
 1869 
     | 
    
         
            +
            book2 = Book.new(2, 'book2')
         
     | 
| 
      
 1870 
     | 
    
         
            +
            book3 = Book.new(3, 'book3')
         
     | 
| 
      
 1871 
     | 
    
         
            +
             
     | 
| 
      
 1872 
     | 
    
         
            +
            author = Author.new(2, [book2, book3, book1])
         
     | 
| 
      
 1873 
     | 
    
         
            +
             
     | 
| 
      
 1874 
     | 
    
         
            +
            class AuthorResource
         
     | 
| 
      
 1875 
     | 
    
         
            +
              include Alba::Resource
         
     | 
| 
      
 1876 
     | 
    
         
            +
             
     | 
| 
      
 1877 
     | 
    
         
            +
              attributes :id
         
     | 
| 
      
 1878 
     | 
    
         
            +
              many :books do
         
     | 
| 
      
 1879 
     | 
    
         
            +
                attributes :id, :name
         
     | 
| 
      
 1880 
     | 
    
         
            +
                attribute :index do |bar|
         
     | 
| 
      
 1881 
     | 
    
         
            +
                  params[:index][bar.id]
         
     | 
| 
      
 1882 
     | 
    
         
            +
                end
         
     | 
| 
      
 1883 
     | 
    
         
            +
              end
         
     | 
| 
      
 1884 
     | 
    
         
            +
            end
         
     | 
| 
      
 1885 
     | 
    
         
            +
             
     | 
| 
      
 1886 
     | 
    
         
            +
            AuthorResource.new(
         
     | 
| 
      
 1887 
     | 
    
         
            +
              author,
         
     | 
| 
      
 1888 
     | 
    
         
            +
              params: {
         
     | 
| 
      
 1889 
     | 
    
         
            +
                index: author.books.map.with_index { |book, index| [book.id, index] }
         
     | 
| 
      
 1890 
     | 
    
         
            +
                .to_h
         
     | 
| 
      
 1891 
     | 
    
         
            +
              }
         
     | 
| 
      
 1892 
     | 
    
         
            +
            ).serialize
         
     | 
| 
      
 1893 
     | 
    
         
            +
            # => {"id":2,"books":[{"id":2,"name":"book2","index":0},{"id":3,"name":"book3","index":1},{"id":1,"name":"book1","index":2}]}
         
     | 
| 
      
 1894 
     | 
    
         
            +
            ```
         
     | 
| 
      
 1895 
     | 
    
         
            +
             
     | 
| 
       1810 
1896 
     | 
    
         
             
            ## Rails
         
     | 
| 
       1811 
1897 
     | 
    
         | 
| 
       1812 
1898 
     | 
    
         
             
            When you use Alba in Rails, you can create an initializer file with the line below for compatibility with Rails JSON encoder.
         
     | 
| 
         @@ -1840,6 +1926,10 @@ To install this gem onto your local machine, run `bundle exec rake install`. To 
     | 
|
| 
       1840 
1926 
     | 
    
         | 
| 
       1841 
1927 
     | 
    
         
             
            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).
         
     | 
| 
       1842 
1928 
     | 
    
         | 
| 
      
 1929 
     | 
    
         
            +
            ## Versioning
         
     | 
| 
      
 1930 
     | 
    
         
            +
             
     | 
| 
      
 1931 
     | 
    
         
            +
            Alba follows [Semver 2.0.0](https://semver.org/spec/v2.0.0.html).
         
     | 
| 
      
 1932 
     | 
    
         
            +
             
     | 
| 
       1843 
1933 
     | 
    
         
             
            ## License
         
     | 
| 
       1844 
1934 
     | 
    
         | 
| 
       1845 
1935 
     | 
    
         
             
            The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
         
     | 
    
        data/lib/alba/resource.rb
    CHANGED
    
    | 
         @@ -14,7 +14,7 @@ module Alba 
     | 
|
| 
       14 
14 
     | 
    
         
             
              module Resource
         
     | 
| 
       15 
15 
     | 
    
         
             
                # @!parse include InstanceMethods
         
     | 
| 
       16 
16 
     | 
    
         
             
                # @!parse extend ClassMethods
         
     | 
| 
       17 
     | 
    
         
            -
                INTERNAL_VARIABLES = {_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, _helper: nil, _resource_methods: [], _select_arity: nil}.freeze # rubocop:disable Layout/LineLength
         
     | 
| 
      
 17 
     | 
    
         
            +
                INTERNAL_VARIABLES = {_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, _helper: nil, _resource_methods: [], _select_arity: nil, _traits: {}}.freeze # rubocop:disable Layout/LineLength
         
     | 
| 
       18 
18 
     | 
    
         
             
                private_constant :INTERNAL_VARIABLES
         
     | 
| 
       19 
19 
     | 
    
         | 
| 
       20 
20 
     | 
    
         
             
                WITHIN_DEFAULT = Object.new.freeze
         
     | 
| 
         @@ -46,10 +46,12 @@ module Alba 
     | 
|
| 
       46 
46 
     | 
    
         
             
                  # @param object [Object] the object to be serialized
         
     | 
| 
       47 
47 
     | 
    
         
             
                  # @param params [Hash] user-given Hash for arbitrary data
         
     | 
| 
       48 
48 
     | 
    
         
             
                  # @param within [Object, nil, false, true] determines what associations to be serialized. If not set, it serializes all associations.
         
     | 
| 
       49 
     | 
    
         
            -
                   
     | 
| 
      
 49 
     | 
    
         
            +
                  # @param with_traits [Symbol, Array<Symbol>, nil] specified traits
         
     | 
| 
      
 50 
     | 
    
         
            +
                  def initialize(object, params: {}, within: WITHIN_DEFAULT, with_traits: nil)
         
     | 
| 
       50 
51 
     | 
    
         
             
                    @object = object
         
     | 
| 
       51 
52 
     | 
    
         
             
                    @params = params
         
     | 
| 
       52 
53 
     | 
    
         
             
                    @within = within
         
     | 
| 
      
 54 
     | 
    
         
            +
                    @with_traits = with_traits
         
     | 
| 
       53 
55 
     | 
    
         
             
                    _setup
         
     | 
| 
       54 
56 
     | 
    
         
             
                  end
         
     | 
| 
       55 
57 
     | 
    
         | 
| 
         @@ -106,6 +108,20 @@ module Alba 
     | 
|
| 
       106 
108 
     | 
    
         | 
| 
       107 
109 
     | 
    
         
             
                  private
         
     | 
| 
       108 
110 
     | 
    
         | 
| 
      
 111 
     | 
    
         
            +
                  def hash_from_traits(obj)
         
     | 
| 
      
 112 
     | 
    
         
            +
                    h = {}
         
     | 
| 
      
 113 
     | 
    
         
            +
                    return h if @with_traits.nil?
         
     | 
| 
      
 114 
     | 
    
         
            +
             
     | 
| 
      
 115 
     | 
    
         
            +
                    Array(@with_traits).each do |trait|
         
     | 
| 
      
 116 
     | 
    
         
            +
                      body = @_traits.fetch(trait) { raise Alba::Error, "Trait not found: #{trait}" }
         
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
      
 118 
     | 
    
         
            +
                      resource_class = Alba.resource_class
         
     | 
| 
      
 119 
     | 
    
         
            +
                      resource_class.class_eval(&body)
         
     | 
| 
      
 120 
     | 
    
         
            +
                      h.merge!(resource_class.new(obj, params: params, within: @within).serializable_hash)
         
     | 
| 
      
 121 
     | 
    
         
            +
                    end
         
     | 
| 
      
 122 
     | 
    
         
            +
                    h
         
     | 
| 
      
 123 
     | 
    
         
            +
                  end
         
     | 
| 
      
 124 
     | 
    
         
            +
             
     | 
| 
       109 
125 
     | 
    
         
             
                  def deprecated_serializable_hash
         
     | 
| 
       110 
126 
     | 
    
         
             
                    Alba.collection?(@object) ? serializable_hash_for_collection : converter.call(@object)
         
     | 
| 
       111 
127 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -212,7 +228,7 @@ module Alba 
     | 
|
| 
       212 
228 
     | 
    
         
             
                    rescue StandardError => e
         
     | 
| 
       213 
229 
     | 
    
         
             
                      handle_error(e, obj, key, attribute, hash)
         
     | 
| 
       214 
230 
     | 
    
         
             
                    end
         
     | 
| 
       215 
     | 
    
         
            -
                    hash
         
     | 
| 
      
 231 
     | 
    
         
            +
                    @with_traits.nil? ? hash : hash.merge!(hash_from_traits(obj))
         
     | 
| 
       216 
232 
     | 
    
         
             
                  end
         
     | 
| 
       217 
233 
     | 
    
         | 
| 
       218 
234 
     | 
    
         
             
                  # This is default behavior for getting attributes for serialization
         
     | 
| 
         @@ -455,6 +471,19 @@ module Alba 
     | 
|
| 
       455 
471 
     | 
    
         
             
                  end
         
     | 
| 
       456 
472 
     | 
    
         
             
                  alias nested nested_attribute
         
     | 
| 
       457 
473 
     | 
    
         | 
| 
      
 474 
     | 
    
         
            +
                  # Set a trait
         
     | 
| 
      
 475 
     | 
    
         
            +
                  #
         
     | 
| 
      
 476 
     | 
    
         
            +
                  # @param name [String, Symbol] name of the trait
         
     | 
| 
      
 477 
     | 
    
         
            +
                  # @param block [Block] the "content" of the trait
         
     | 
| 
      
 478 
     | 
    
         
            +
                  # @raise [ArgumentError] if block is absent
         
     | 
| 
      
 479 
     | 
    
         
            +
                  # @return [void]
         
     | 
| 
      
 480 
     | 
    
         
            +
                  def trait(name, &block)
         
     | 
| 
      
 481 
     | 
    
         
            +
                    raise ArgumentError, 'No block given in trait method' unless block
         
     | 
| 
      
 482 
     | 
    
         
            +
             
     | 
| 
      
 483 
     | 
    
         
            +
                    name = name.to_sym
         
     | 
| 
      
 484 
     | 
    
         
            +
                    @_traits[name] = block
         
     | 
| 
      
 485 
     | 
    
         
            +
                  end
         
     | 
| 
      
 486 
     | 
    
         
            +
             
     | 
| 
       458 
487 
     | 
    
         
             
                  # Set root key
         
     | 
| 
       459 
488 
     | 
    
         
             
                  #
         
     | 
| 
       460 
489 
     | 
    
         
             
                  # @param key [String, Symbol]
         
     | 
    
        data/lib/alba/version.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | 
         @@ -1,13 +1,13 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: alba
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 3. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 3.7.0
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - OKURA Masafumi
         
     | 
| 
       8 
8 
     | 
    
         
             
            bindir: exe
         
     | 
| 
       9 
9 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       10 
     | 
    
         
            -
            date: 2025- 
     | 
| 
      
 10 
     | 
    
         
            +
            date: 2025-05-08 00:00:00.000000000 Z
         
     | 
| 
       11 
11 
     | 
    
         
             
            dependencies: []
         
     | 
| 
       12 
12 
     | 
    
         
             
            description: Alba is the fastest JSON serializer for Ruby. It focuses on performance,
         
     | 
| 
       13 
13 
     | 
    
         
             
              flexibility and usability.
         
     | 
| 
         @@ -40,7 +40,7 @@ licenses: 
     | 
|
| 
       40 
40 
     | 
    
         
             
            metadata:
         
     | 
| 
       41 
41 
     | 
    
         
             
              bug_tracker_uri: https://github.com/okuramasafumi/alba/issues
         
     | 
| 
       42 
42 
     | 
    
         
             
              changelog_uri: https://github.com/okuramasafumi/alba/blob/main/CHANGELOG.md
         
     | 
| 
       43 
     | 
    
         
            -
              documentation_uri: https:// 
     | 
| 
      
 43 
     | 
    
         
            +
              documentation_uri: https://okuramasafumi.github.io/alba/
         
     | 
| 
       44 
44 
     | 
    
         
             
              source_code_uri: https://github.com/okuramasafumi/alba
         
     | 
| 
       45 
45 
     | 
    
         
             
              rubygems_mfa_required: 'true'
         
     | 
| 
       46 
46 
     | 
    
         
             
            rdoc_options: []
         
     |