Skip to content

Commit f690789

Browse files
author
Артём Большаков
committed
Move all associations related code to Associations module
1 parent eddf4e7 commit f690789

File tree

2 files changed

+123
-102
lines changed

2 files changed

+123
-102
lines changed

lib/active_model/serializer.rb

Lines changed: 3 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,13 @@ class Serializer
77
autoload :Configuration
88
autoload :ArraySerializer
99
autoload :Adapter
10-
autoload :Association
11-
autoload :Reflection
12-
autoload :SingularReflection
13-
autoload :CollectionReflection
14-
autoload :BelongsToReflection
15-
autoload :HasOneReflection
16-
autoload :HasManyReflection
17-
10+
autoload :Associations
1811
include Configuration
12+
include Associations
1913

2014
class << self
2115
attr_accessor :_attributes
2216
attr_accessor :_attributes_keys
23-
attr_accessor :_reflections
2417
attr_accessor :_urls
2518
attr_accessor :_cache
2619
attr_accessor :_fragmented
@@ -34,10 +27,10 @@ class << self
3427
def self.inherited(base)
3528
base._attributes = self._attributes.try(:dup) || []
3629
base._attributes_keys = self._attributes_keys.try(:dup) || {}
37-
base._reflections = self._reflections.try(:dup) || []
3830
base._urls = []
3931
serializer_file = File.open(caller.first[/^[^:]+/])
4032
base._cache_digest = Digest::MD5.hexdigest(serializer_file.read)
33+
super
4134
end
4235

4336
def self.attributes(*attrs)
@@ -74,57 +67,6 @@ def self.cache(options = {})
7467
@_cache_options = (options.empty?) ? nil : options
7568
end
7669

77-
# Defines an association in the object should be rendered.
78-
#
79-
# The serializer object should implement the association name
80-
# as a method which should return an array when invoked. If a method
81-
# with the association name does not exist, the association name is
82-
# dispatched to the serialized object.
83-
def self.has_many(*attrs)
84-
associate attrs do |name, options|
85-
HasManyReflection.new(name, options)
86-
end
87-
end
88-
89-
# Defines an association in the object that should be rendered.
90-
#
91-
# The serializer object should implement the association name
92-
# as a method which should return an object when invoked. If a method
93-
# with the association name does not exist, the association name is
94-
# dispatched to the serialized object.
95-
def self.belongs_to(*attrs)
96-
associate attrs do |name, options|
97-
BelongsToReflection.new(name, options)
98-
end
99-
end
100-
101-
# Defines an association in the object should be rendered.
102-
#
103-
# The serializer object should implement the association name
104-
# as a method which should return an object when invoked. If a method
105-
# with the association name does not exist, the association name is
106-
# dispatched to the serialized object.
107-
def self.has_one(*attrs)
108-
associate attrs do |name, options|
109-
HasOneReflection.new(name, options)
110-
end
111-
end
112-
113-
def self.associate(attrs, &block) #:nodoc:
114-
options = attrs.extract_options!
115-
self._reflections = _reflections.dup
116-
117-
attrs.each do |name|
118-
unless method_defined?(name)
119-
define_method name do
120-
object.send name
121-
end
122-
end
123-
124-
self._reflections << block.call(name, options)
125-
end
126-
end
127-
12870
def self.url(attr)
12971
@_urls.push attr
13072
end
@@ -211,51 +153,10 @@ def attributes(options = {})
211153
end
212154
end
213155

214-
215-
def associations
216-
return unless object
217-
218-
Enumerator.new do |y|
219-
self.class._reflections.dup.each do |reflection|
220-
name = reflection.name
221-
association_value = send(name)
222-
reflection_options = reflection.options.dup
223-
serializer_class = ActiveModel::Serializer.serializer_for(association_value, reflection_options)
224-
225-
if serializer_class
226-
begin
227-
serializer = serializer_class.new(
228-
association_value,
229-
serializer_options(reflection_options)
230-
)
231-
rescue ActiveModel::Serializer::ArraySerializer::NoSerializerError
232-
virtual_value = association_value
233-
virtual_value = virtual_value.as_json if virtual_value.respond_to?(:as_json)
234-
reflection_options[:virtual_value] = virtual_value
235-
end
236-
elsif !association_value.nil? && !association_value.instance_of?(Object)
237-
reflection_options[:virtual_value] = association_value
238-
end
239-
240-
y.yield Association.new(name, serializer, reflection_options)
241-
end
242-
end
243-
end
244-
245156
def self.serializers_cache
246157
@serializers_cache ||= ThreadSafe::Cache.new
247158
end
248159

249-
private
250-
251-
def serializer_options(reflection_options)
252-
serializer = reflection_options.fetch(:serializer, nil)
253-
254-
serializer_options = options.except(:serializer)
255-
serializer_options[:serializer] = serializer if serializer
256-
serializer_options
257-
end
258-
259160
attr_reader :options
260161

261162
def self.get_serializer_for(klass)
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
module ActiveModel
2+
class Serializer
3+
module Associations
4+
extend ActiveSupport::Concern
5+
6+
included do |base|
7+
class << base
8+
attr_accessor :_reflections
9+
end
10+
11+
autoload :Association
12+
autoload :Reflection
13+
autoload :SingularReflection
14+
autoload :CollectionReflection
15+
autoload :BelongsToReflection
16+
autoload :HasOneReflection
17+
autoload :HasManyReflection
18+
end
19+
20+
module ClassMethods
21+
def inherited(base)
22+
base._reflections = self._reflections.try(:dup) || []
23+
end
24+
25+
# Defines an association in the object should be rendered.
26+
#
27+
# The serializer object should implement the association name
28+
# as a method which should return an array when invoked. If a method
29+
# with the association name does not exist, the association name is
30+
# dispatched to the serialized object.
31+
def has_many(*attrs)
32+
associate attrs do |name, options|
33+
HasManyReflection.new(name, options)
34+
end
35+
end
36+
37+
# Defines an association in the object that should be rendered.
38+
#
39+
# The serializer object should implement the association name
40+
# as a method which should return an object when invoked. If a method
41+
# with the association name does not exist, the association name is
42+
# dispatched to the serialized object.
43+
def belongs_to(*attrs)
44+
associate attrs do |name, options|
45+
BelongsToReflection.new(name, options)
46+
end
47+
end
48+
49+
# Defines an association in the object should be rendered.
50+
#
51+
# The serializer object should implement the association name
52+
# as a method which should return an object when invoked. If a method
53+
# with the association name does not exist, the association name is
54+
# dispatched to the serialized object.
55+
def has_one(*attrs)
56+
associate attrs do |name, options|
57+
HasOneReflection.new(name, options)
58+
end
59+
end
60+
61+
private
62+
63+
def associate(attrs, &block) #:nodoc:
64+
options = attrs.extract_options!
65+
self._reflections = _reflections.dup
66+
67+
attrs.each do |name|
68+
unless method_defined?(name)
69+
define_method name do
70+
object.send name
71+
end
72+
end
73+
74+
self._reflections << block.call(name, options)
75+
end
76+
end
77+
end
78+
79+
def associations
80+
return unless object
81+
82+
Enumerator.new do |y|
83+
self.class._reflections.dup.each do |reflection|
84+
name = reflection.name
85+
association_value = send(name)
86+
reflection_options = reflection.options.dup
87+
serializer_class = ActiveModel::Serializer.serializer_for(association_value, reflection_options)
88+
89+
if serializer_class
90+
begin
91+
serializer = serializer_class.new(
92+
association_value,
93+
serializer_options(reflection_options)
94+
)
95+
rescue ActiveModel::Serializer::ArraySerializer::NoSerializerError
96+
virtual_value = association_value
97+
virtual_value = virtual_value.as_json if virtual_value.respond_to?(:as_json)
98+
reflection_options[:virtual_value] = virtual_value
99+
end
100+
elsif !association_value.nil? && !association_value.instance_of?(Object)
101+
reflection_options[:virtual_value] = association_value
102+
end
103+
104+
y.yield Association.new(name, serializer, reflection_options)
105+
end
106+
end
107+
end
108+
109+
private
110+
111+
def serializer_options(reflection_options)
112+
serializer = reflection_options.fetch(:serializer, nil)
113+
114+
serializer_options = options.except(:serializer)
115+
serializer_options[:serializer] = serializer if serializer
116+
serializer_options
117+
end
118+
end
119+
end
120+
end

0 commit comments

Comments
 (0)