Factor out ancestor class Field of Attribute and Reflection.

This commit is contained in:
Lucas Hosseini 2016-01-04 20:40:56 +01:00
parent 6860318133
commit 40ed7b57bd
3 changed files with 87 additions and 74 deletions

View File

@ -1,40 +1,25 @@
require 'active_model/serializer/field'
module ActiveModel
class Serializer
Attribute = Struct.new(:name, :options, :block) do
def value(serializer)
if block
serializer.instance_eval(&block)
else
serializer.read_attribute_for_serialization(name)
end
end
def included?(serializer)
case condition
when :if
serializer.public_send(condition)
when :unless
!serializer.public_send(condition)
else
true
end
end
private
def condition_type
if options.key?(:if)
:if
elsif options.key?(:unless)
:unless
else
:none
end
end
def condition
options[condition_type]
end
# Holds all the meta-data about an attribute as it was specified in the
# ActiveModel::Serializer class.
#
# @example
# class PostSerializer < ActiveModel::Serializer
# attribute :content
# attribute :name, key: :title
# attribute :email, key: :author_email, if: :user_logged_in?
# attribute :preview do
# truncate(object.content)
# end
#
# def user_logged_in?
# current_user.logged_in?
# end
# end
#
class Attribute < Field
end
end
end

View File

@ -0,0 +1,55 @@
module ActiveModel
class Serializer
# Holds all the meta-data about a field (i.e. attribute or association) as it was
# specified in the ActiveModel::Serializer class.
# Notice that the field block is evaluated in the context of the serializer.
Field = Struct.new(:name, :options, :block) do
# Compute the actual value of a field for a given serializer instance.
# @param [Serializer] The serializer instance for which the value is computed.
# @return [Object] value
#
# @api private
#
def value(serializer)
if block
serializer.instance_eval(&block)
else
serializer.read_attribute_for_serialization(name)
end
end
# Decide whether the field should be serialized by the given serializer instance.
# @param [Serializer] The serializer instance
# @return [Bool]
#
# @api private
#
def included?(serializer)
case condition
when :if
serializer.public_send(condition)
when :unless
!serializer.public_send(condition)
else
true
end
end
private
def condition_type
if options.key?(:if)
:if
elsif options.key?(:unless)
:unless
else
:none
end
end
def condition
options[condition_type]
end
end
end
end

View File

@ -1,18 +1,24 @@
require 'active_model/serializer/field'
module ActiveModel
class Serializer
# Holds all the meta-data about an association as it was specified in the
# ActiveModel::Serializer class.
#
# @example
# class PostSerializer < ActiveModel::Serializer
# class PostSerializer < ActiveModel::Serializer
# has_one :author, serializer: AuthorSerializer
# has_many :comments
# has_many :comments, key: :last_comments do
# object.comments.last(1)
# end
# end
# has_many :secret_meta_data, if: :is_admin?
#
# def is_admin?
# current_user.admin?
# end
# end
#
# Notice that the association block is evaluated in the context of the serializer.
# Specifically, the association 'comments' is evaluated two different ways:
# 1) as 'comments' and named 'comments'.
# 2) as 'object.comments.last(1)' and named 'last_comments'.
@ -21,32 +27,13 @@ module ActiveModel
# # [
# # HasOneReflection.new(:author, serializer: AuthorSerializer),
# # HasManyReflection.new(:comments)
# # HasManyReflection.new(:comments, { key: :last_comments }, #<Block>)
# # HasManyReflection.new(:secret_meta_data, { if: :is_admin? })
# # ]
#
# So you can inspect reflections in your Adapters.
#
Reflection = Struct.new(:name, :options, :block) do
# @api private
def value(instance)
if block
instance.instance_eval(&block)
else
instance.read_attribute_for_serialization(name)
end
end
# @api private
def included?(serializer)
case condition_type
when :if
serializer.public_send(condition)
when :unless
!serializer.public_send(condition)
else
true
end
end
class Reflection < Field
# Build association. This method is used internally to
# build serializer's association by its reflection.
#
@ -91,20 +78,6 @@ module ActiveModel
private
def condition_type
if options.key?(:if)
:if
elsif options.key?(:unless)
:unless
else
:none
end
end
def condition
options[condition_type]
end
def serializer_options(subject, parent_serializer_options, reflection_options)
serializer = reflection_options.fetch(:serializer, nil)