Module: ActiveModel::Serialization
Relationships & Source Files | |
Extension / Inclusion / Inheritance Descendants | |
Included In:
| |
Defined in: | activemodel/lib/active_model/serialization.rb |
Overview
Provides a basic serialization to a serializable_hash for your objects.
A minimal implementation could be:
class Person
include ActiveModel::Serialization
attr_accessor :name
def attributes
{'name' => nil}
end
end
Which would provide you with:
person = Person.new
person.serializable_hash # => {"name"=>nil}
person.name = "Bob"
person.serializable_hash # => {"name"=>"Bob"}
An attributes
hash must be defined and should contain any attributes you need to be serialized. Attributes
must be strings, not symbols. When called, serializable hash will use instance methods that match the name of the attributes hash’s keys. In order to override this behavior, override the #read_attribute_for_serialization method.
Serializers::JSON
module automatically includes the Serialization
module, so there is no need to explicitly include Serialization
.
A minimal implementation including JSON would be:
class Person
include ActiveModel::Serializers::JSON
attr_accessor :name
def attributes
{'name' => nil}
end
end
Which would provide you with:
person = Person.new
person.serializable_hash # => {"name"=>nil}
person.as_json # => {"name"=>nil}
person.to_json # => "{\"name\":null}"
person.name = "Bob"
person.serializable_hash # => {"name"=>"Bob"}
person.as_json # => {"name"=>"Bob"}
person.to_json # => "{\"name\":\"Bob\"}"
Valid options are :only
, :except
, :methods
and :include
. The following are all valid examples:
person.serializable_hash(only: 'name')
person.serializable_hash(include: :address)
person.serializable_hash(include: { address: { only: 'city' }})
Instance Method Summary
-
#read_attribute_for_serialization
Hook method defining how an attribute value should be retrieved for serialization.
-
#serializable_hash(options = nil)
Returns a serialized hash of your object.
- #attribute_names_for_serialization private
- #serializable_attributes(attribute_names) private
-
#serializable_add_includes(options = {})
private
Internal use only
Add associations specified via the
:include
option.
Instance Method Details
#attribute_names_for_serialization (private)
[ GitHub ]# File 'activemodel/lib/active_model/serialization.rb', line 170
def attribute_names_for_serialization attributes.keys end
#read_attribute_for_serialization
Hook method defining how an attribute value should be retrieved for serialization. By default this is assumed to be an instance named after the attribute. Override this method in subclasses should you need to retrieve the value for a given attribute differently:
class MyClass
include ActiveModel::Serialization
def initialize(data = {})
@data = data
end
def read_attribute_for_serialization(key)
@data[key]
end
end
# File 'activemodel/lib/active_model/serialization.rb', line 167
alias :read_attribute_for_serialization :send
#serializable_add_includes(options = {}) (private)
Add associations specified via the :include
option.
Expects a block that takes as arguments:
{association} - name of the association
{records} - the association record(s) to be serialized
{opts} - for the association records
# File 'activemodel/lib/active_model/serialization.rb', line 184
def serializable_add_includes( = {}) # :nodoc: return unless includes = [:include] unless includes.is_a?(Hash) includes = Hash[Array(includes).flat_map { |n| n.is_a?(Hash) ? n.to_a : [[n, {}]] }] end includes.each do |association, opts| if records = send(association) yield association, records, opts end end end
#serializable_attributes(attribute_names) (private)
[ GitHub ]# File 'activemodel/lib/active_model/serialization.rb', line 174
def serializable_attributes(attribute_names) attribute_names.index_with { |n| read_attribute_for_serialization(n) } end
#serializable_hash(options = nil)
Returns a serialized hash of your object.
class Person
include ActiveModel::Serialization
attr_accessor :name, :age
def attributes
{'name' => nil, 'age' => nil}
end
def capitalized_name
name.capitalize
end
end
person = Person.new
person.name = 'bob'
person.age = 22
person.serializable_hash # => {"name"=>"bob", "age"=>22}
person.serializable_hash(only: :name) # => {"name"=>"bob"}
person.serializable_hash(except: :name) # => {"age"=>22}
person.serializable_hash(methods: :capitalized_name)
# => {"name"=>"bob", "age"=>22, "capitalized_name"=>"Bob"}
Example with :include
option
class User
include ActiveModel::Serializers::JSON
attr_accessor :name, :notes # Emulate has_many :notes
def attributes
{'name' => nil}
end
end
class Note
include ActiveModel::Serializers::JSON
attr_accessor :title, :text
def attributes
{'title' => nil, 'text' => nil}
end
end
note = Note.new
note.title = 'Battle of Austerlitz'
note.text = 'Some text here'
user = User.new
user.name = 'Napoleon'
user.notes = [note]
user.serializable_hash
# => {"name" => "Napoleon"}
user.serializable_hash(include: { notes: { only: 'title' }})
# => {"name" => "Napoleon", "notes" => [{"title"=>"Battle of Austerlitz"}]}
# File 'activemodel/lib/active_model/serialization.rb', line 125
def serializable_hash( = nil) attribute_names = attribute_names_for_serialization return serializable_attributes(attribute_names) if .blank? if only = [:only] attribute_names = Array(only).map(&:to_s) & attribute_names elsif except = [:except] attribute_names -= Array(except).map(&:to_s) end hash = serializable_attributes(attribute_names) Array( [:methods]).each { |m| hash[m.to_s] = send(m) } serializable_add_includes( ) do |association, records, opts| hash[association.to_s] = if records.respond_to?(:to_ary) records.to_ary.map { |a| a.serializable_hash(opts) } else records.serializable_hash(opts) end end hash end