Skip to content

Commit 656b232

Browse files
committed
Factor out ancestor class Field of Attribute and Reflection.
1 parent 0641f25 commit 656b232

File tree

3 files changed

+87
-74
lines changed

3 files changed

+87
-74
lines changed
Lines changed: 20 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,25 @@
1+
require 'active_model/serializer/field'
2+
13
module ActiveModel
24
class Serializer
3-
Attribute = Struct.new(:name, :options, :block) do
4-
def value(serializer)
5-
if block
6-
serializer.instance_eval(&block)
7-
else
8-
serializer.read_attribute_for_serialization(name)
9-
end
10-
end
11-
12-
def included?(serializer)
13-
case condition
14-
when :if
15-
serializer.public_send(condition)
16-
when :unless
17-
!serializer.public_send(condition)
18-
else
19-
true
20-
end
21-
end
22-
23-
private
24-
25-
def condition_type
26-
if options.key?(:if)
27-
:if
28-
elsif options.key?(:unless)
29-
:unless
30-
else
31-
:none
32-
end
33-
end
34-
35-
def condition
36-
options[condition_type]
37-
end
5+
# Holds all the meta-data about an attribute as it was specified in the
6+
# ActiveModel::Serializer class.
7+
#
8+
# @example
9+
# class PostSerializer < ActiveModel::Serializer
10+
# attribute :content
11+
# attribute :name, key: :title
12+
# attribute :email, key: :author_email, if: :user_logged_in?
13+
# attribute :preview do
14+
# truncate(object.content)
15+
# end
16+
#
17+
# def user_logged_in?
18+
# current_user.logged_in?
19+
# end
20+
# end
21+
#
22+
class Attribute < Field
3823
end
3924
end
4025
end

lib/active_model/serializer/field.rb

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
module ActiveModel
2+
class Serializer
3+
# Holds all the meta-data about a field (i.e. attribute or association) as it was
4+
# specified in the ActiveModel::Serializer class.
5+
# Notice that the field block is evaluated in the context of the serializer.
6+
Field = Struct.new(:name, :options, :block) do
7+
# Compute the actual value of a field for a given serializer instance.
8+
# @param [Serializer] The serializer instance for which the value is computed.
9+
# @return [Object] value
10+
#
11+
# @api private
12+
#
13+
def value(serializer)
14+
if block
15+
serializer.instance_eval(&block)
16+
else
17+
serializer.read_attribute_for_serialization(name)
18+
end
19+
end
20+
21+
# Decide whether the field should be serialized by the given serializer instance.
22+
# @param [Serializer] The serializer instance
23+
# @return [Bool]
24+
#
25+
# @api private
26+
#
27+
def included?(serializer)
28+
case condition
29+
when :if
30+
serializer.public_send(condition)
31+
when :unless
32+
!serializer.public_send(condition)
33+
else
34+
true
35+
end
36+
end
37+
38+
private
39+
40+
def condition_type
41+
if options.key?(:if)
42+
:if
43+
elsif options.key?(:unless)
44+
:unless
45+
else
46+
:none
47+
end
48+
end
49+
50+
def condition
51+
options[condition_type]
52+
end
53+
end
54+
end
55+
end

lib/active_model/serializer/reflection.rb

Lines changed: 12 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,24 @@
1+
require 'active_model/serializer/field'
2+
13
module ActiveModel
24
class Serializer
35
# Holds all the meta-data about an association as it was specified in the
46
# ActiveModel::Serializer class.
57
#
68
# @example
7-
# class PostSerializer < ActiveModel::Serializer
9+
# class PostSerializer < ActiveModel::Serializer
810
# has_one :author, serializer: AuthorSerializer
911
# has_many :comments
1012
# has_many :comments, key: :last_comments do
1113
# object.comments.last(1)
1214
# end
13-
# end
15+
# has_many :secret_meta_data, if: :is_admin?
16+
#
17+
# def is_admin?
18+
# current_user.admin?
19+
# end
20+
# end
1421
#
15-
# Notice that the association block is evaluated in the context of the serializer.
1622
# Specifically, the association 'comments' is evaluated two different ways:
1723
# 1) as 'comments' and named 'comments'.
1824
# 2) as 'object.comments.last(1)' and named 'last_comments'.
@@ -21,32 +27,13 @@ class Serializer
2127
# # [
2228
# # HasOneReflection.new(:author, serializer: AuthorSerializer),
2329
# # HasManyReflection.new(:comments)
30+
# # HasManyReflection.new(:comments, { key: :last_comments }, #<Block>)
31+
# # HasManyReflection.new(:secret_meta_data, { if: :is_admin? })
2432
# # ]
2533
#
2634
# So you can inspect reflections in your Adapters.
2735
#
28-
Reflection = Struct.new(:name, :options, :block) do
29-
# @api private
30-
def value(instance)
31-
if block
32-
instance.instance_eval(&block)
33-
else
34-
instance.read_attribute_for_serialization(name)
35-
end
36-
end
37-
38-
# @api private
39-
def included?(serializer)
40-
case condition_type
41-
when :if
42-
serializer.public_send(condition)
43-
when :unless
44-
!serializer.public_send(condition)
45-
else
46-
true
47-
end
48-
end
49-
36+
class Reflection < Field
5037
# Build association. This method is used internally to
5138
# build serializer's association by its reflection.
5239
#
@@ -91,20 +78,6 @@ def build_association(subject, parent_serializer_options)
9178

9279
private
9380

94-
def condition_type
95-
if options.key?(:if)
96-
:if
97-
elsif options.key?(:unless)
98-
:unless
99-
else
100-
:none
101-
end
102-
end
103-
104-
def condition
105-
options[condition_type]
106-
end
107-
10881
def serializer_options(subject, parent_serializer_options, reflection_options)
10982
serializer = reflection_options.fetch(:serializer, nil)
11083

0 commit comments

Comments
 (0)