Class: Avo::Fields::BelongsToField
Overview
Requirements
- list
- ID
- label
- Type
- foreign_key
- foreign_key for poly type
- foreign_key for poly id
- is_disabled?
Defined Under Namespace
Classes: EditComponent, IndexComponent, ShowComponent
Instance Attribute Summary collapse
Attributes inherited from BaseField
#action, #autocomplete, #block, #computable, #computed, #computed_value, #copyable, #default, #for_attribute, #for_presentation_only, #format_display_using, #format_edit_using, #format_form_using, #format_index_using, #format_new_using, #format_show_using, #format_using, #id, #label_help, #null_values, #nullable, #panel_name, #readonly, #record, #required, #size, #sortable, #stacked, #summarizable, #user, #width
#disabled
#html
#show_on_edit, #show_on_index, #show_on_new, #show_on_preview, #show_on_show
#visible
#resource, #view
Instance Method Summary
collapse
-
#can_create?(final_target_resource = target_resource) ⇒ Boolean
field :user, as: :belongs_to, can_create: true Only can create when: - can_create: true option is present - target resource's policy allow creation (UserPolicy in this example).
-
#database_id ⇒ Object
-
#database_value ⇒ Object
-
#default_name ⇒ Object
-
#default_placeholder ⇒ Object
-
#field_label ⇒ Object
What the user sees in the text field.
-
#field_value ⇒ Object
-
#fill_field(record, key, value, params) ⇒ Object
-
#foreign_key ⇒ Object
-
#form_field_label ⇒ Object
-
#get_record ⇒ Object
-
#id_input_foreign_key ⇒ Object
-
#index_link_to_record ⇒ Object
-
#index_link_to_resource ⇒ Object
-
#initialize(id, **args, &block) ⇒ BelongsToField
constructor
A new instance of BelongsToField.
-
#is_polymorphic? ⇒ Boolean
-
#label ⇒ Object
-
#options ⇒ Object
-
#polymorphic_form_field_label ⇒ Object
-
#reflection ⇒ Object
Get the model reflection instance.
-
#reflection_for_key(key) ⇒ Object
-
#relation_model_class ⇒ Object
-
#target_resource(record: @record, polymorphic_model_class: value&.class) ⇒ Object
-
#to_permitted_param ⇒ Object
-
#type_input_foreign_key ⇒ Object
-
#valid_polymorphic_class(possible_class) ⇒ Object
-
#value ⇒ Object
-
#values_for_type(model = nil) ⇒ Object
-
#visible_in_reflection?(reflection = nil) ⇒ Boolean
When displayed inside a has_one/has_many reflection, hide this field if it points back to the parent record (i.e., it is the inverse of the reflection).
#use_resource
#is_searchable?
Methods inherited from BaseField
#apply_update_using, #assign_value, #attribute_id, #custom?, #custom_name?, #execute_context, #has_attribute?, #has_own_panel?, #help, #hidden_in_reflection?, #meta, #name, #name_override, #options_for_filter, #parent, #placeholder, #plural_name, #record_errors, #resolve_attribute, #resource_scoped_translation_key, #sentence_name, #shared_translation_key, #table_header_class, #table_header_label, #translated_name, #translated_plural_name, #translation_key, #type, #updatable, #width_class, #width_option
#model_name, #to_key
#component_for_view, #view_component_name, #view_component_namespace
#is_required?
#is_disabled?
#is_readonly?
#get_html
#computed_default_value
#helpers
#except_on, #hide_on, #initialize_views, #only_on, #post_initialize, #show_on, #show_on_create, #show_on_update, #visible_in_view?
#visible?
#is_card?, #is_collaboration?, #is_field?, #is_header?, #is_heading?, #is_panel?, #is_sidebar?, #is_tab?, #is_tab_group?, #is_tool?
#visible?
#hydrate
Constructor Details
#initialize(id, **args, &block) ⇒ BelongsToField
Returns a new instance of BelongsToField.
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
# File 'lib/avo/fields/belongs_to_field.rb', line 73
def initialize(id, **args, &block)
super
@searchable = (args[:searchable] == true || args[:searchable].is_a?(Hash)) ? args[:searchable] : false
@polymorphic_as = args[:polymorphic_as]
@types = args[:types]
@relation_method = attribute_id.to_s.parameterize.underscore
@allow_via_detaching = args[:allow_via_detaching] == true
@attach_scope = args[:attach_scope]
@polymorphic_help = args[:polymorphic_help]
@target = args[:target]
@use_resource = args[:use_resource] || nil
@can_create = args[:can_create].nil? || args[:can_create]
@link_to_record = args[:link_to_record].present? ? args[:link_to_record] : false
@link_to_child_resource = args[:link_to_child_resource]
end
|
Instance Attribute Details
#allow_via_detaching ⇒ Object
Returns the value of attribute allow_via_detaching.
67
68
69
|
# File 'lib/avo/fields/belongs_to_field.rb', line 67
def allow_via_detaching
@allow_via_detaching
end
|
#attach_scope ⇒ Object
Returns the value of attribute attach_scope.
68
69
70
|
# File 'lib/avo/fields/belongs_to_field.rb', line 68
def attach_scope
@attach_scope
end
|
#link_to_child_resource ⇒ Object
Returns the value of attribute link_to_child_resource.
71
72
73
|
# File 'lib/avo/fields/belongs_to_field.rb', line 71
def link_to_child_resource
@link_to_child_resource
end
|
#link_to_record ⇒ Object
Returns the value of attribute link_to_record.
70
71
72
|
# File 'lib/avo/fields/belongs_to_field.rb', line 70
def link_to_record
@link_to_record
end
|
#polymorphic_as ⇒ Object
Returns the value of attribute polymorphic_as.
65
66
67
|
# File 'lib/avo/fields/belongs_to_field.rb', line 65
def polymorphic_as
@polymorphic_as
end
|
#polymorphic_help ⇒ Object
Returns the value of attribute polymorphic_help.
69
70
71
|
# File 'lib/avo/fields/belongs_to_field.rb', line 69
def polymorphic_help
@polymorphic_help
end
|
#target ⇒ Object
Returns the value of attribute target.
63
64
65
|
# File 'lib/avo/fields/belongs_to_field.rb', line 63
def target
@target
end
|
#types ⇒ Object
for Polymorphic associations
66
67
68
|
# File 'lib/avo/fields/belongs_to_field.rb', line 66
def types
@types
end
|
Instance Method Details
#can_create?(final_target_resource = target_resource) ⇒ Boolean
field :user, as: :belongs_to, can_create: true
Only can create when:
- `can_create: true` option is present
- target resource's policy allow creation (UserPolicy in this example)
305
306
307
|
# File 'lib/avo/fields/belongs_to_field.rb', line 305
def can_create?(final_target_resource = target_resource)
@can_create && final_target_resource.authorization.authorize_action(:create, raise_exception: false)
end
|
#database_id ⇒ Object
240
241
242
243
244
245
246
247
|
# File 'lib/avo/fields/belongs_to_field.rb', line 240
def database_id
return :"#{polymorphic_as}_type" if polymorphic_as.present?
foreign_key
rescue
attribute_id
end
|
#database_value ⇒ Object
135
136
137
138
139
|
# File 'lib/avo/fields/belongs_to_field.rb', line 135
def database_value
target_resource.id
rescue
nil
end
|
#default_name ⇒ Object
279
280
281
282
283
|
# File 'lib/avo/fields/belongs_to_field.rb', line 279
def default_name
return polymorphic_as.to_s.humanize if polymorphic_as.present?
super
end
|
#default_placeholder ⇒ Object
90
91
92
|
# File 'lib/avo/fields/belongs_to_field.rb', line 90
def default_placeholder
I18n.t("avo.choose_an_option")
end
|
#field_label ⇒ Object
What the user sees in the text field
112
113
114
|
# File 'lib/avo/fields/belongs_to_field.rb', line 112
def field_label
label
end
|
#field_value ⇒ Object
105
106
107
108
109
|
# File 'lib/avo/fields/belongs_to_field.rb', line 105
def field_value
value.send(database_value)
rescue
nil
end
|
#fill_field(record, key, value, params) ⇒ Object
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
|
# File 'lib/avo/fields/belongs_to_field.rb', line 201
def fill_field(record, key, value, params)
return record unless record.methods.include? key.to_sym
if polymorphic_as.present?
valid_model_class = valid_polymorphic_class params[:"#{polymorphic_as}_type"]
record.send(:"#{polymorphic_as}_type=", valid_model_class)
id_from_param = params["#{polymorphic_as}_id"]
if valid_model_class.blank? || id_from_param.blank?
record.send(:"#{polymorphic_as}_id=", nil)
else
target = target_resource(record:, polymorphic_model_class: value.safe_constantize)
record_id = target.find_record(id_from_param, query: scoped_target_query(target, record, for_find: true)).id
record.send(:"#{polymorphic_as}_id=", record_id)
end
else
target = target_resource(record:)
record_id = if value.blank?
value
else
target.find_record(value, query: scoped_target_query(target, record, for_find: true)).send(reflection.association_primary_key)
end
record.send(:"#{key}=", record_id)
end
record
end
|
#foreign_key ⇒ Object
161
162
163
164
165
166
167
168
169
|
# File 'lib/avo/fields/belongs_to_field.rb', line 161
def foreign_key
@foreign_key ||= if polymorphic_as.present?
polymorphic_as
elsif @record.present?
get_model_class(@record).reflections[@relation_method].foreign_key
elsif @resource.present? && @resource.model_class.reflections[@relation_method].present?
@resource.model_class.reflections[@relation_method].foreign_key
end
end
|
309
310
311
|
# File 'lib/avo/fields/belongs_to_field.rb', line 309
def form_field_label
"#{id}_id"
end
|
#get_record ⇒ Object
275
276
277
|
# File 'lib/avo/fields/belongs_to_field.rb', line 275
def get_record
@record || @resource.record
end
|
147
148
149
150
151
152
153
|
# File 'lib/avo/fields/belongs_to_field.rb', line 147
def id_input_foreign_key
if is_polymorphic?
"#{foreign_key}_id"
else
foreign_key
end
end
|
#index_link_to_record ⇒ Object
293
294
295
296
297
298
299
|
# File 'lib/avo/fields/belongs_to_field.rb', line 293
def index_link_to_record
if @link_to_record.present?
get_record
else
value
end
end
|
#index_link_to_resource ⇒ Object
285
286
287
288
289
290
291
|
# File 'lib/avo/fields/belongs_to_field.rb', line 285
def index_link_to_resource
if @link_to_record.present?
@resource
else
target_resource
end
end
|
#is_polymorphic? ⇒ Boolean
155
156
157
158
159
|
# File 'lib/avo/fields/belongs_to_field.rb', line 155
def is_polymorphic?
polymorphic_as.present?
rescue
false
end
|
#label ⇒ Object
188
189
190
191
|
# File 'lib/avo/fields/belongs_to_field.rb', line 188
def label
return if target_resource.blank?
target_resource.new(record: value)&.record_title
end
|
#options ⇒ Object
116
117
118
|
# File 'lib/avo/fields/belongs_to_field.rb', line 116
def options
values_for_type
end
|
313
314
315
|
# File 'lib/avo/fields/belongs_to_field.rb', line 313
def polymorphic_form_field_label
"#{id}_type"
end
|
#reflection ⇒ Object
Get the model reflection instance
178
179
180
181
182
|
# File 'lib/avo/fields/belongs_to_field.rb', line 178
def reflection
reflection_for_key(attribute_id)
rescue
nil
end
|
#reflection_for_key(key) ⇒ Object
171
172
173
174
175
|
# File 'lib/avo/fields/belongs_to_field.rb', line 171
def reflection_for_key(key)
get_model_class(get_record).reflections[key.to_s]
rescue
nil
end
|
#relation_model_class ⇒ Object
184
185
186
|
# File 'lib/avo/fields/belongs_to_field.rb', line 184
def relation_model_class
@resource.model_class
end
|
#target_resource(record: @record, polymorphic_model_class: value&.class) ⇒ Object
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
|
# File 'lib/avo/fields/belongs_to_field.rb', line 249
def target_resource(record: @record, polymorphic_model_class: value&.class)
@target_resource ||= if use_resource.present?
use_resource
elsif is_polymorphic?
if polymorphic_model_class.present?
get_resource_by_model_class(polymorphic_model_class)
else
return nil
end
else
reflection_key = polymorphic_as || attribute_id
reflection_object = record.class.reflect_on_association(reflection_key)
if (link_to_child_resource || @resource&.link_to_child_resource) && value.present?
get_resource_by_model_class(value.class.to_s)
elsif reflection_object.klass.present?
get_resource_by_model_class(reflection_object.klass.to_s)
elsif reflection_object.options[:class_name].present?
get_resource_by_model_class(reflection_object.options[:class_name])
else
App.get_resource_by_name reflection_key
end
end
end
|
#to_permitted_param ⇒ Object
193
194
195
196
197
198
199
|
# File 'lib/avo/fields/belongs_to_field.rb', line 193
def to_permitted_param
if polymorphic_as.present?
return [:"#{polymorphic_as}_type", :"#{polymorphic_as}_id"]
end
foreign_key.to_sym
end
|
141
142
143
144
145
|
# File 'lib/avo/fields/belongs_to_field.rb', line 141
def type_input_foreign_key
if is_polymorphic?
"#{foreign_key}_type"
end
end
|
#valid_polymorphic_class(possible_class) ⇒ Object
234
235
236
237
238
|
# File 'lib/avo/fields/belongs_to_field.rb', line 234
def valid_polymorphic_class(possible_class)
types.find do |type|
type.to_s == possible_class.to_s
end
end
|
#value ⇒ Object
94
95
96
97
98
99
100
101
102
|
# File 'lib/avo/fields/belongs_to_field.rb', line 94
def value
if is_polymorphic?
super(polymorphic_as)
else
super(@relation_method)
end
end
|
#values_for_type(model = nil) ⇒ Object
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
# File 'lib/avo/fields/belongs_to_field.rb', line 120
def values_for_type(model = nil)
resource = target_resource
resource = Avo.resource_manager.get_resource_by_model_class model if model.present?
query = scoped_target_query(resource, get_record)
lookup_list_limit = Avo.configuration.associations[:lookup_list_limit]
query.all.limit(lookup_list_limit).map do |record|
[resource.new(record: record).record_title, record.to_param]
end.tap do |options|
options << t("avo.more_records_available") if options.size == lookup_list_limit
end
end
|
#visible_in_reflection?(reflection = nil) ⇒ Boolean
When displayed inside a has_one/has_many reflection, hide this field if it
points back to the parent record (i.e., it is the inverse of the reflection).
This mirrors the filtering logic in Avo::Concerns::HasItems#get_fields.
320
321
322
323
324
325
326
327
328
329
330
|
# File 'lib/avo/fields/belongs_to_field.rb', line 320
def visible_in_reflection?(reflection = nil)
return true if reflection.nil?
return true unless respond_to?(:foreign_key)
return true unless reflection.inverse_of.present?
return true unless reflection.inverse_of.respond_to?(:foreign_key)
inverse_fk = reflection.inverse_of.foreign_key
self_fk = is_polymorphic? ? self.reflection&.foreign_key : foreign_key
inverse_fk != self_fk
end
|