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.**