Mutils
Introduction
mutils is a collection of useful helpers for Ruby and Rails applications.
Serialization is one of the features available today, and the gem is intended to grow into a broader utility toolkit over time.
Table of Contents
- Mutils
- Introduction
- Table of Contents
- Features
- Installation
- Usage
- Rails Generator
- Attributes
- Relations
- Conditional Attributes
- Conditional Relations
- Attributes Blocks
- Attributes Blocks with Params
- Custom Methods
- Name Tag
- Options
- Sample Usage
- Or
- Or In Controllers
- Contributing
- License
- Code of Conduct
- Security
Features
- Simple declaration syntax similar to Active Model Serializer
- Relationships support
belongs_to,has_many,has_one - Block style attributes with params
Installation
Add this line to your application's Gemfile:
gem 'mutils'And then execute:
bundle installOr install it yourself as:
gem install mutilsUsage
Rails Generator
rails g mutils:serializer User id first_name last_name email
OUTPUT
Running via Spring preloader in process xxxxx
create app/serializers/user_serializer.rbYou will get serializer in app/serializers/user_serializer.rb
# frozen_string_literal: true
# User Serializer
class UserSerializer < Mutils::Serialization::BaseSerializer
attributes :id, :first_name, :last_name, :email
endAttributes
Attributes are fields in the model itself. You can reference them by below example
# frozen_string_literal: true
# User Serializer
class UserSerializer < Mutils::Serialization::BaseSerializer
attributes :id, :first_name, :last_name, :email
## OR
attribute :email, {always_include: true} ## this will allow to selectively include email
## OR
attribute :email, &:email ## this will call email attribute from User
endRelations
Relations such as has_many, belongs_to, has_one can be used as follows
- Every relation must be provided with their own serializer
-
always_includeoption can be used to instructSerializerto always include this relation -
always_includeby default is disabled, relations which are notalways_includecan be included while using the serializer. Refer to next section for this usage -
labeloption can be used to override model class name while serializing
# frozen_string_literal: true
# User Serializer
class UserSerializer < Mutils::Serialization::BaseSerializer
attributes :id, :first_name, :last_name, :email
belongs_to :company, serializer: CompanySerializer, always_include: true
## OR
belongs_to :company, serializer: CompanySerializer, always_include: true, label: 'organization' ##<== important to give singular name
has_many :comments, serializer: CommentSerializer
has_one :account, serializer: AccountSerializer
def full_name
"#{scope.first_name} #{scope.last_name}"
end
endConditional Attributes
Serializer can have conditional attributes with if: Proc
if: Proc block can receive scope and params as arguments
- in proc {|scope|}, scope is object which is being serialized
- in proc {|scope,params|}, scope is object which is being serialized and params is hash given to Serializer as second arguments in {params:anything}
# frozen_string_literal: true
# User Serializer
class UserSerializer < Mutils::Serialization::BaseSerializer
attributes :id, :first_name, :last_name
attribute :email, if: proc { |scope| scope.name == 'mutils' } ## Email will only serialize if user's name is 'mutils'
# OR with Params
attribute :email, if: proc { |scope,params| params && params[:show_email] == true } ## Email will only serialize if params[:show_email] is true
end
UserSerializer.new(user) # Without params
UserSerializer.new(user,{params:{show_email:true}}) # With paramsConditional Relations
Serializer can have conditional relations with if: Proc
if: Proc block can receive scope and params as arguments
- in proc {|scope|}, scope is object which is being serialized
- in proc {|scope,params|}, scope is object which is being serialized and params is hash given to Serializer as second arguments in {params:anything}
# frozen_string_literal: true
# User Serializer
class UserSerializer < Mutils::Serialization::BaseSerializer
attributes :id, :first_name, :last_name
has_many :comments, serializer: CommentSerializer, if: proc { |scope| scope.name == 'mutils' } ## comments will only serialize if user's name is 'mutils'
belongs_to :account, serializer: AccountSerializer, if: proc { |scope| scope.name != 'mutils' } ## account will only serialize if user's name is not 'mutils'
# OR with Params
belongs_to :account, serializer: AccountSerializer, if: proc { |scope,params| params && params[:show_account] == true } ## account will only serialize if params[:show_account] is true
end
UserSerializer.new(user) # Without params
UserSerializer.new(user,{params:{show_account:true}}) # With paramsAttributes Blocks
While writing attribute a block can be provided for useful transformations like full_name as shown below
# frozen_string_literal: true
# User Serializer
class UserSerializer < Mutils::Serialization::BaseSerializer
attributes :id, :first_name, :last_name, :email
attribute :full_name do |object|
"#{object.first_name} #{object.last_name}"
end
endAttributes Blocks with Params
While writing attribute a block can be provided for useful transformations like full_name as shown below
# frozen_string_literal: true
# User Serializer
class UserSerializer < Mutils::Serialization::BaseSerializer
attributes :id, :first_name, :last_name, :email
attribute :is_owner do |object,params|
params[:owner].id == object.id ? true:false
end
end# in controller
user = current_user
owner = owner_user
render json: UserSerializer.new(user,{params:{owner:owner}})Custom Methods
Custom methods used in Serializer can be useful for cases as below.
scope will be available to reference object in Serializer in below case its user
# frozen_string_literal: true
# User Serializer
class UserSerializer < Mutils::Serialization::BaseSerializer
attributes :id, :first_name, :last_name, :email
###
custom_methods :full_name
## OR
custom_method :full_name, {always_include: true} ## this will allow to selectively include full_name
###
def full_name
"#{scope.first_name} #{scope.last_name}"
end
endName Tag
name_tag is used to provide custom name to serializer output keys for json
Options
-
name_tag 'Person', true# Include Person or People in JSON serialization as root, true|false this only implies to root serializer -
name_tag 'Person', false# not Include Person or People in JSON serialization as root, true|false this only implies to root serializer -
name_tag 'Person'# same asname_tag 'Person', false - without name_tag, actual class name of scope object inside serializer will be used
# frozen_string_literal: true
# User Serializer
class UserSerializer < Mutils::Serialization::BaseSerializer
name_tag 'Person', true
attributes :id, :first_name, :last_name, :email
custom_methods :full_name
def full_name
"#{scope.first_name} #{scope.last_name}"
end
endSample Usage
user = User.first
options = {includes: [:comments,:account]}
UserSerializer.new(user,options).to_hOr
users = User.all
options = {includes: [:account]}
UserSerializer.new(users,options).to_jsonOr In Controllers
users = User.all
options = {includes: [:account]}
users_serializer =UserSerializer.new(users,options)
render json: users_serializerContributing
Bug Reports and PR's are welcomed in this repository kindly follow guidelines from .github directory.
License
The gem is available as open source under the terms of the MIT License.
Code of Conduct
Everyone interacting in the Mutils project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.
Security
For security refer to security document.