ArSerializer
- JSONの形をclientからリクエストできる
- N+1 SQLを避ける
Install
gem 'ar_serializer'
Field定義
class User < ActiveRecord::Base
has_many :posts
serializer_field :id, :name, :posts
end
class Post < ActiveRecord::Base
has_many :comments
serializer_field :id, :title, :body, :comments
serializer_field :comment_count, count_of: :comments
end
class Comment < ActiveRecord::Base
serializer_field :id, :body
end
Serialize
ArSerializer.serialize Post.find(params[:id]), params[:query]
Query
ArSerializer.serialize user, :*
ArSerializer.serialize user, [:id, :name, posts: [:id, :title, comments: :id]]
ArSerializer.serialize user, { id: true, name: true, posts: { id: true, title: true, comments: :id } }
ArSerializer.serialize posts, [:title, :body, comment_count: { as: :num_replies }]
その他
class Comment < ActiveRecord::Base
serializer_field :username, includes: :user do
{ ja: user.name + '先生', en: 'Dr.' + user.name }
end
end
class Foo < ActiveRecord::Base
define_preloader :bar_count_loader do |models|
Bar.where(foo_id: models.map(&:id)).group(:foo_id).count
end
serializer_field :bar_count, preload: preloader_name_or_proc do |preloaded|
preloaded[id] || 0
end
end
class Post < ActiveRecord::Base
has_many :comments
serializer_field :comments
end
ArSerializer.serialize Post.all, comments: [:id, params: { order: { id: :desc }, limit: 2 }]
class Post < ActiveRecord::Base
serializer_field :created_at do |context, params|
created_at.in_time_zone(context[:tz]).strftime params[:format]
end
end
ArSerializer.serialize post, { created_at: { params: { format: '%H:%M:%S' } } }, context: { tz: 'Tokyo' }
class Foo < ActiveRecord::Base
def foo_bar; end
serializer_field :fooBar
end
class Foo
include ArSerializer::Serializable
def bar; end
serializer_field :bar
end
class User < ActiveRecord::Base
serializer_field :name
serializer_field(:foo, namespace: :admin) { :foo }
serializer_field(:bar, namespace: :superadmin) { :bar }
end
ArSerializer.serialize user, [:name, :foo] ArSerializer.serialize user, [:name, :foo], use: :admin
ArSerializer.serialize user, [:name, :foo, :bar], use: [:admin, :superadmin]
class User < ActiveRecord::Base
serializer_field :o_posts, association: :posts, only: :title
serializer_field :e_posts, association: :posts, except: :comments
end
ArSerializer.serialize user, o_posts: :title, e_posts: :body
ArSerializer.serialize user, o_posts: :*, e_posts: :*
ArSerializer.serialize user, o_posts: :body ArSerializer.serialize user, e_posts: :comments
class User < ActiveRecord::Base
serializer_field(:posts, params_type: { title: :string? }) do |title: nil|
title ? posts.where(title: title) : posts
end
serializer_field :foobar, type: ['foo', 'bar', { foobar: [:string, nil] }] do
['foo', 'bar', { foobar: nil }, { foobar: 'foobar' }].sample
end
serializer_field :published_posts, type: -> { [Post] }
end
ArSerializer::TypeScript.generate_type_definition User
class MySchema
include ArSerializer::Serializable
serializer_field :post, type: Post do |context, id:|
Post.find id
end
serializer_field :user, type: :string, params_type: { name: :string } do |context, params|
User.find_by name: params[:name]
end
serializer_field :__schema do
ArSerializer::GraphQL::SchemaClass.new self.class
end
end
ArSerializer::GraphQL.definition MySchema ArSerializer::GraphQL.serialize MySchema.new, '{post(id: 1){title} user(name: user1){id name}}'
ArSerializer::GraphQL.serialize MySchema.new, '{__schema{types{name fields{ name}}}}', operation_name: nil, variables: {}