Skip to content

Commit

Permalink
Migrate from active_model_serializers
Browse files Browse the repository at this point in the history
  • Loading branch information
tashirosota committed Jul 29, 2021
1 parent 755a9c6 commit 0eeb5d2
Showing 1 changed file with 357 additions and 0 deletions.
357 changes: 357 additions & 0 deletions docs/migrate_from_active_model_serializers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,357 @@
---
title: Upgrading from ActiveModelSerializers
---

<!-- @format -->

This guide is aimed at helping ActiveModelSerializers users transition to Alba, and it consists of three parts:

1. Basic serialization
2. Complex serialization
3. Unsupported features

## Example class

TODO:
Example clsss is included `ActiveModel::Model`, 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).This example also works with ActiveRecord.

```rb
class User
attr_reader :id, :created_at, :updated_at
attr_accessor :profile, :articles

def initialize(id)
@id = id
@created_at = Time.now
@updated_at = Time.now
@articles = []
end
end

class Profile
attr_reader :user_id, :email

def initialize(user_id, email)
@user_id = user_id
@email = email
end
end

class Article
attr_accessor :user_id, :title, :body

def initialize(user_id, title, body)
@user_id = user_id
@title = title
@body = body
end
end
```

## 1. Basic serialization

### #serializable_hash

- or #as_json, #to_json

#### When ActiveModelSerializer

```rb
# Infer and use by "#{MODEL_NAME}Serializer" in app/serializers/user_serializer.rb
class UserSerializer < ActiveModel::Serializer
type :user
attributes :id, :created_at, :updated_at
end

# serialze
ActiveModelSerializers::SerializableResource.new(
user, # User instance
).serializable_hash
# => {
# user: {
# id: id,
# created_at: created_at,
# updated_at: updated_at
# }
# }
```

#### When Alba

```rb
# Infer and use by "#{MODEL_NAME}Resource"
# In app/resources/user_resource.rb
class UserResource
include Alba::Resource
attributes :id, :created_at, :updated_at
end

# serialze
UserResource.new(user).serializable_hash
# => {
# id: id,
# created_at: created_at,
# updated_at: updated_at,
# }

# If want `user key`
class UserResource
include Alba::Resource
root_key :user # Call root_key method like ActiveModel::Serializer#type
attributes :id, :created_at, :updated_at
end

# serialze
JSON.parse UserResource.new(user).serialize # !!!!serializable_hash does not support root key!!! Must use JSON.parse and serialize
# => {
# "user"=>{
# "id"=>id,
# "created_at"=>created_at,
# "updated_at"=>updated_at
# }
# }
# If want symbolize keys with #deep_symbolize_keys in Rails
JSON.parse(UserResource.new(user).serialize).deep_symbolize_keys
# => {
# user: {
# id: id,
# created_at: created_at,
# updated_at: updated_at
# }
# }
```

## 2. Complex serialization

### Serialize collections

#### ActiveModelSerializer

```rb
class UserSerializer < ActiveModel::Serializer
type :user
attributes :id, :created_at, :updated_at
end

ActiveModelSerializers::SerializableResource.new(
users,
adapter: :attributes # Comment out this line if you want users key
# Want to specified key to call with root: args
).serializable_hash
# => [{:id=>1, :created_at=>created_at, :updated_at=>updated_at},
# {:id=>2, :created_at=>created_at, :updated_at=>updated_at},
# {:id=>3, :created_at=>created_at, :updated_at=>updated_at}]
```

#### Alba

```rb
class UserResource
include Alba::Resource
attributes :id, :created_at, :updated_at
end
UserResource.new(users).serializable_hash
# =>[{:id=>1, :created_at=>created_at, :updated_at=>updated_at},
# {:id=>2, :created_at=>created_at, :updated_at=>updated_at},
# {:id=>3, :created_at=>created_at, :updated_at=>updated_at}]
# or
JSON.parse UserResource.new(users).serialize(root_key: :users)
# => {"users"=>
# [{"id"=>1, "created_at"=>created_at, "updated_at"=>updated_at},
# {"id"=>2, "created_at"=>created_at, "updated_at"=>updated_at},
# {"id"=>3, "created_at"=>created_at, "updated_at"=>updated_at}]}
```

### Nested serialization

#### ActiveModelSerializer

```rb
class ProfileSerializer < ActiveModel::Serializer
type :profile
attributes :email
end

class ArticleSerializer < ActiveModel::Serializer
type :article
attributes :title, :body
end

class UserSerializer < ActiveModel::Serializer
type :user
attributes :id, :created_at, :updated_at
has_one :profile, serializer: ProfileSerializer # For has_one relation
has_many :articles, serializer: ArticleSerializer # For has_many relation
end

ActiveModelSerializers::SerializableResource.new(
user
).serializable_hash
# => {
# :user=> {
# :id=>1,
# :created_at=>created_at,
# :updated_at=>updated_at,
# :profile=> {
# :email=>email
# },
# :articles => [
# {
# :title=>title,
# :body=>body
# }
# ]
# }
# }
```

#### When Alba

```rb
class ProfileResource
include Alba::Resource
root_key :profile
attributes :email
end

class ArticleResource
include Alba::Resource
root_key :article
attributes :title, :body
end

class UserResource
include Alba::Resource
root_key :user
attributes :id, :created_at, :updated_at
one :profile, resource: ProfileResource # For has_one relation
many :articles, resource: ArticleResource # For has_many relation
end

UserResource.new(user).serializable_hash
# => {
# :id=>1,
# :created_at=>created_at,
# :updated_at=>updated_at,
# :profile=> {
# :email=>email
# },
# :articles => [
# {
# :title=>title,
# :body=>body
# }
# ]
# }
```

### Serialize with custom serializer

#### ActiveModelSerializer

```rb
class CustomUserSerialzier < ActiveModel::Serializer
type :user
attribute :email do
object.profile.email
end
end

# serialze
ActiveModelSerializers::SerializableResource.new(
user,
serializer: ::CustomUserSerialzier # Call with serializer arg
).serializable_hash
# => {
# user: {
# email: email
# }
# }
```

#### Alba

```rb
class CustomUserResource
include Alba::Resource
root_key :user
attribute :email do
object.profile.email
end
end

# serialze
CustomUserResource.new(user).serializable_hash
# => {
# email: email
# }
```

### Passing arbitrary options to a serializer

#### ActiveModelSerializer

```rb
class UserSerializer < ApplicationSerializer
type :user
attributes :id, :created_at, :updated_at
attribute :custom_params do
pp instance_options
# => given_params: { a: :b }
instance_options # Access by instance_options method
end
end

# serialze
ActiveModelSerializers::SerializableResource.new(
user,
given_params: { a: :b } # Give with your favorite keyword argument
).serializable_hash
# => {
# :id=>1,
# :created_at=>created_at,
# :updated_at=>updated_at,
# :custom_params=>{
# :given_params=>{
# :a=>:b
# }
# }
# }
```

#### Alba

```rb
class UserResource
include Alba::Resource
root_key :user
attributes :id, :created_at, :updated_at
attribute :custom_params do
pp params
# => { :a=>:b }
params
end
end

# serialze
UserResource.new(
user,
params: { a: :b } # Give with :params keyword argument
).serializable_hash
# => {
# :id=>1,
# :created_at=>created_at,
# :updated_at=>updated_at,
# :custom_params=>{
# :a=>:b
# }
# }
```

## 3. Unsupported features

- [RelationshipLinks](https://github.com/rails-api/active_model_serializers/blob/v0.10.6/docs/howto/add_relationship_links.md)
- [PaginationLinks](https://github.com/rails-api/active_model_serializers/blob/v0.10.6/docs/howto/add_pagination_links.md)
- [Logging](https://github.com/rails-api/active_model_serializers/blob/v0.10.6/docs/general/logging.md)
- [Caching](https://github.com/rails-api/active_model_serializers/blob/v0.10.6/docs/general/caching.md)
- [Rendering](https://github.com/rails-api/active_model_serializers/blob/v0.10.6/docs/general/rendering.md)

0 comments on commit 0eeb5d2

Please sign in to comment.