Class: ViewModel::ActiveRecord::AssociationData
- Inherits:
-
Object
- Object
- ViewModel::ActiveRecord::AssociationData
show all
- Defined in:
- lib/view_model/active_record/association_data.rb
Defined Under Namespace
Classes: InvalidAssociation
Instance Attribute Summary collapse
Instance Method Summary
collapse
Constructor Details
#initialize(owner:, association_name:, direct_association_name:, indirect_association_name:, target_viewmodels:, external:, through_order_attr:, read_only:) ⇒ AssociationData
Returns a new instance of AssociationData.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
# File 'lib/view_model/active_record/association_data.rb', line 8
def initialize(owner:,
association_name:,
direct_association_name:,
indirect_association_name:,
target_viewmodels:,
external:,
through_order_attr:,
read_only:)
@association_name = association_name
@direct_reflection = owner.model_class.reflect_on_association(direct_association_name)
if @direct_reflection.nil?
raise InvalidAssociation.new("Association '#{direct_association_name}' not found in model '#{owner.model_class.name}'")
end
@indirect_association_name = indirect_association_name
@read_only = read_only
@external = external
@through_order_attr = through_order_attr
@target_viewmodels = target_viewmodels
@initialized = false
@mutex = Mutex.new
end
|
Instance Attribute Details
#association_name ⇒ Object
Returns the value of attribute association_name.
6
7
8
|
# File 'lib/view_model/active_record/association_data.rb', line 6
def association_name
@association_name
end
|
#direct_reflection ⇒ Object
Returns the value of attribute direct_reflection.
6
7
8
|
# File 'lib/view_model/active_record/association_data.rb', line 6
def direct_reflection
@direct_reflection
end
|
Instance Method Details
#accepts?(viewmodel_class) ⇒ Boolean
189
190
191
|
# File 'lib/view_model/active_record/association_data.rb', line 189
def accepts?(viewmodel_class)
viewmodel_classes.include?(viewmodel_class)
end
|
#association? ⇒ Boolean
90
91
92
|
# File 'lib/view_model/active_record/association_data.rb', line 90
def association?
true
end
|
#collection? ⇒ Boolean
227
228
229
|
# File 'lib/view_model/active_record/association_data.rb', line 227
def collection?
through? || direct_reflection.collection?
end
|
#direct_reflection_inverse(foreign_class = nil) ⇒ Object
150
151
152
153
154
155
156
|
# File 'lib/view_model/active_record/association_data.rb', line 150
def direct_reflection_inverse(foreign_class = nil)
if direct_reflection.polymorphic?
direct_reflection.polymorphic_inverse_of(foreign_class)
else
direct_reflection.inverse_of
end
end
|
#direct_viewmodel ⇒ Object
220
221
222
223
224
225
|
# File 'lib/view_model/active_record/association_data.rb', line 220
def direct_viewmodel
raise ArgumentError.new('not a through association') unless through?
lazy_initialize! unless @initialized
@direct_viewmodel
end
|
#external? ⇒ Boolean
112
113
114
|
# File 'lib/view_model/active_record/association_data.rb', line 112
def external?
@external
end
|
#indirect_association_data ⇒ Object
231
232
233
|
# File 'lib/view_model/active_record/association_data.rb', line 231
def indirect_association_data
direct_viewmodel._association_data(indirect_reflection.name)
end
|
#indirect_reflection ⇒ Object
145
146
147
148
|
# File 'lib/view_model/active_record/association_data.rb', line 145
def indirect_reflection
lazy_initialize! unless @initialized
@indirect_reflection
end
|
#lazy_initialize! ⇒ Object
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
# File 'lib/view_model/active_record/association_data.rb', line 36
def lazy_initialize!
@mutex.synchronize do
return if @initialized
if through?
intermediate_model = @direct_reflection.klass
@indirect_reflection = load_indirect_reflection(intermediate_model, @indirect_association_name)
target_reflection = @indirect_reflection
else
target_reflection = @direct_reflection
end
@viewmodel_classes =
if @target_viewmodels.present?
@target_viewmodels.map { |v| resolve_viewmodel_class(v) }
else
if target_reflection.polymorphic?
raise InvalidAssociation.new(
'Cannot automatically infer target viewmodels from polymorphic association')
end
infer_viewmodel_class(target_reflection.klass)
end
@referenced = @viewmodel_classes.first.root?
@owned = !@referenced || (target_reflection.macro != :belongs_to)
unless @viewmodel_classes.all? { |v| v.root? == @referenced }
raise InvalidAssociation.new('Invalid association target: mixed root and non-root viewmodels')
end
if external? && !@referenced
raise InvalidAssociation.new('External associations must be to root viewmodels')
end
if through?
unless @referenced
raise InvalidAssociation.new('Through associations must be to root viewmodels')
end
@direct_viewmodel = build_direct_viewmodel(@direct_reflection, @indirect_reflection,
@viewmodel_classes, @through_order_attr)
end
@initialized = true
end
end
|
#nested? ⇒ Boolean
99
100
101
|
# File 'lib/view_model/active_record/association_data.rb', line 99
def nested?
!referenced?
end
|
#ordered? ⇒ Boolean
201
202
203
204
205
206
207
208
209
210
211
212
213
214
|
# File 'lib/view_model/active_record/association_data.rb', line 201
def ordered?
@ordered ||=
if through?
direct_viewmodel._list_member?
else
list_members = viewmodel_classes.map { |c| c._list_member? }.uniq
if list_members.size > 1
raise ArgumentError.new('Inconsistent associated views: mixed list membership')
end
list_members[0]
end
end
|
#owned? ⇒ Boolean
103
104
105
106
|
# File 'lib/view_model/active_record/association_data.rb', line 103
def owned?
lazy_initialize! unless @initialized
@owned
end
|
#pointer_location ⇒ Object
The side of the immediate association that holds the pointer.
136
137
138
139
140
141
142
143
|
# File 'lib/view_model/active_record/association_data.rb', line 136
def pointer_location
case direct_reflection.macro
when :belongs_to
:local
when :has_one, :has_many
:remote
end
end
|
#polymorphic? ⇒ Boolean
129
130
131
132
133
|
# File 'lib/view_model/active_record/association_data.rb', line 129
def polymorphic?
target_reflection.polymorphic? || viewmodel_classes.size > 1
end
|
#read_only? ⇒ Boolean
116
117
118
|
# File 'lib/view_model/active_record/association_data.rb', line 116
def read_only?
@read_only
end
|
#referenced? ⇒ Boolean
94
95
96
97
|
# File 'lib/view_model/active_record/association_data.rb', line 94
def referenced?
lazy_initialize! unless @initialized
@referenced
end
|
#shared? ⇒ Boolean
108
109
110
|
# File 'lib/view_model/active_record/association_data.rb', line 108
def shared?
!owned?
end
|
#target_reflection ⇒ Object
reflection for the target of this association: indirect if through, direct otherwise
121
122
123
124
125
126
127
|
# File 'lib/view_model/active_record/association_data.rb', line 121
def target_reflection
if through?
indirect_reflection
else
direct_reflection
end
end
|
#through? ⇒ Boolean
216
217
218
|
# File 'lib/view_model/active_record/association_data.rb', line 216
def through?
@indirect_association_name.present?
end
|
#viewmodel_class ⇒ Object
193
194
195
196
197
198
199
|
# File 'lib/view_model/active_record/association_data.rb', line 193
def viewmodel_class
unless viewmodel_classes.size == 1
raise ArgumentError.new("More than one possible class for association '#{target_reflection.name}'")
end
viewmodel_classes.first
end
|
#viewmodel_class_for_model(model_class) ⇒ Object
163
164
165
|
# File 'lib/view_model/active_record/association_data.rb', line 163
def viewmodel_class_for_model(model_class)
model_to_viewmodel[model_class]
end
|
#viewmodel_class_for_model!(model_class) ⇒ Object
167
168
169
170
171
172
173
174
|
# File 'lib/view_model/active_record/association_data.rb', line 167
def viewmodel_class_for_model!(model_class)
vm_class = viewmodel_class_for_model(model_class)
if vm_class.nil?
raise ArgumentError.new(
"Invalid viewmodel model for association '#{target_reflection.name}': '#{model_class.name}'")
end
vm_class
end
|
#viewmodel_class_for_name(name) ⇒ Object
176
177
178
|
# File 'lib/view_model/active_record/association_data.rb', line 176
def viewmodel_class_for_name(name)
name_to_viewmodel[name]
end
|
#viewmodel_class_for_name!(name) ⇒ Object
180
181
182
183
184
185
186
187
|
# File 'lib/view_model/active_record/association_data.rb', line 180
def viewmodel_class_for_name!(name)
vm_class = viewmodel_class_for_name(name)
if vm_class.nil?
raise ArgumentError.new(
"Invalid viewmodel name for association '#{target_reflection.name}': '#{name}'")
end
vm_class
end
|
#viewmodel_classes ⇒ Object
158
159
160
161
|
# File 'lib/view_model/active_record/association_data.rb', line 158
def viewmodel_classes
lazy_initialize! unless @initialized
@viewmodel_classes
end
|