README.md in alba-1.3.0 vs README.md in alba-1.4.0

- old
+ new

@@ -1,9 +1,10 @@ [![Gem Version](https://badge.fury.io/rb/alba.svg)](https://badge.fury.io/rb/alba) [![CI](https://github.com/okuramasafumi/alba/actions/workflows/main.yml/badge.svg)](https://github.com/okuramasafumi/alba/actions/workflows/main.yml) [![codecov](https://codecov.io/gh/okuramasafumi/alba/branch/master/graph/badge.svg?token=3D3HEZ5OXT)](https://codecov.io/gh/okuramasafumi/alba) [![Maintainability](https://api.codeclimate.com/v1/badges/fdab4cc0de0b9addcfe8/maintainability)](https://codeclimate.com/github/okuramasafumi/alba/maintainability) +[![Inline docs](http://inch-ci.org/github/okuramasafumi/alba.svg?branch=main)](http://inch-ci.org/github/okuramasafumi/alba) ![GitHub code size in bytes](https://img.shields.io/github/languages/code-size/okuramasafumi/alba) ![GitHub](https://img.shields.io/github/license/okuramasafumi/alba) # Alba @@ -96,10 +97,20 @@ ```ruby Alba.backend = :oj ``` +#### Encoder configuration + +You can also set JSON encoder directly with a Proc. + +```ruby +Alba.encoder = ->(object) { JSON.generate(object) } +``` + +You can consider setting a backend with Symbol as a shortcut to set encoder. + #### Inference configuration You can enable inference feature using `enable_inference!` method. ```ruby @@ -196,10 +207,39 @@ UserResource.new(user).serialize # => '{"id":1,"articles":[{"title":"Hello World!"},{"title":"Super nice"}]}' ``` +You can define associations inline if you don't need a class for association. + +```ruby +class ArticleResource + include Alba::Resource + + attributes :title +end + +class UserResource + include Alba::Resource + + attributes :id + + many :articles, resource: ArticleResource +end + +# This class works the same as `UserResource` +class AnotherUserResource + include Alba::Resource + + attributes :id + + many :articles do + attributes :title + end +end +``` + ### Inline definition with `Alba.serialize` `Alba.serialize` method is a shortcut to define everything inline. ```ruby @@ -210,10 +250,17 @@ end end # => '{"foo":{"id":1,"articles":[{"title":"Hello World!","body":"Hello World!!!"},{"title":"Super nice","body":"Really nice!"}]}}' ``` +`Alba.serialize` can be used when you don't know what kind of object you serialize. For example: + +```ruby +Alba.serialize(something) +# => Same as `FooResource.new(something).serialize` when `something` is an instance of `Foo`. +``` + Although this might be useful sometimes, it's generally recommended to define a class for Resource. ### Inheritance and Ignorance You can `exclude` or `ignore` certain attributes using `ignoring`. @@ -233,17 +280,16 @@ include Alba::Resource attributes :id, :name, :body end -class RestrictedFooResouce < GenericFooResource +class RestrictedFooResource < GenericFooResource ignoring :id, :body end -RestrictedFooResouce.new(foo).serialize +RestrictedFooResource.new(foo).serialize # => '{"name":"my foo"}' -end ``` ### Key transformation If you want to use `transform_keys` DSL and you already have `active_support` installed, key transformation will work out of the box, using `ActiveSupport::Inflector`. If `active_support` is not around, you have 2 possibilities: @@ -400,10 +446,24 @@ user = User.new(1, nil, nil) UserResource.new(user).serialize # => '{"id":1}' ``` +### Default + +Alba doesn't support default value for attributes, but it's easy to set a default value. + +```ruby +class FooResource + attribute :bar do |foo| + foo.bar || 'default bar' + end +end +``` + +We believe this is clearer than using some (not implemented yet) DSL such as `default` because there are some conditions where default values should be applied (`nil`, `blank?`, `empty?` etc.) + ### Inference After `Alba.enable_inference!` called, Alba tries to infer root key and association resource name. ```ruby @@ -507,9 +567,57 @@ else [key, error.message] end end ``` + +### Metadata + +You can set a metadata with `meta` DSL or `meta` option. + +```ruby +class UserResource + include Alba::Resource + + root_key :user, :users + + attributes :id, :name + + meta do + if object.is_a?(Enumerable) + {size: object.size} + else + {foo: :bar} + end + end +end + +user = User.new(1, 'Masafumi OKURA', 'masafumi@example.com') +UserResource.new([user]).serialize +# => '{"users":[{"id":1,"name":"Masafumi OKURA"}],"meta":{"size":1}}' + +# You can merge metadata with `meta` option + +UserResource.new([user]).serialize(meta: {foo: :bar}) +# => '{"users":[{"id":1,"name":"Masafumi OKURA"}],"meta":{"size":1,"foo":"bar"}}' + +# You can set metadata with `meta` option alone + +class UserResourceWithoutMeta + include Alba::Resource + + root_key :user, :users + + attributes :id, :name +end + +UserResource.new([user]).serialize(meta: {foo: :bar}) +# => '{"users":[{"id":1,"name":"Masafumi OKURA"}],"meta":{"foo":"bar"}}' +``` + +You can use `object` method to access the underlying object and `params` to access the params in `meta` block. + +Note that setting root key is required when setting a metadata. ### Circular associations control **Note that this feature works correctly since version 1.3. In previous versions it doesn't work as expected.**