Class: Avo::Fields::BelongsToField
- Includes:
- Concerns::IsSearchable, Concerns::UseResource
- Defined in:
- lib/avo/fields/belongs_to_field.rb
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
-
#allow_via_detaching ⇒ Object
readonly
Returns the value of attribute allow_via_detaching.
-
#attach_scope ⇒ Object
readonly
Returns the value of attribute attach_scope.
-
#link_to_child_resource ⇒ Object
readonly
Returns the value of attribute link_to_child_resource.
-
#link_to_record ⇒ Object
readonly
Returns the value of attribute link_to_record.
-
#polymorphic_as ⇒ Object
readonly
Returns the value of attribute polymorphic_as.
-
#polymorphic_help ⇒ Object
readonly
Returns the value of attribute polymorphic_help.
-
#target ⇒ Object
Returns the value of attribute target.
-
#types ⇒ Object
readonly
for Polymorphic associations.
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, #help, #id, #label_help, #null_values, #nullable, #panel_name, #readonly, #record, #required, #size, #sortable, #stacked, #summarizable, #user, #width
Attributes included from Concerns::IsDisabled
Attributes included from Concerns::HasHTMLAttributes
Attributes included from Concerns::VisibleInDifferentViews
#show_on_edit, #show_on_index, #show_on_new, #show_on_preview, #show_on_show
Attributes included from Concerns::IsVisible
Attributes included from Concerns::IsResourceItem
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
-
#field_label ⇒ Object
What the user sees in the text field.
-
#field_value ⇒ Object
The value.
- #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).
Methods included from Concerns::UseResource
Methods included from Concerns::IsSearchable
Methods inherited from BaseField
#apply_update_using, #assign_value, #attribute_id, #custom?, #custom_name?, #execute_context, #has_attribute?, #has_own_panel?, #hidden_in_reflection?, #meta, #name, #name_override, #options_for_filter, #parent, #placeholder, #plural_name, #record_errors, #resolve_attribute, #table_header_class, #table_header_label, #translated_name, #translated_plural_name, #translation_key, #type, #updatable, #width_class, #width_option
Methods included from Concerns::DomId
Methods included from Concerns::UseViewComponents
#component_for_view, #view_component_name, #view_component_namespace
Methods included from Concerns::IsRequired
Methods included from Concerns::IsDisabled
Methods included from Concerns::IsReadonly
Methods included from Concerns::HasHTMLAttributes
Methods included from Concerns::HasDefault
Methods included from Concerns::HasHelpers
Methods included from Concerns::VisibleInDifferentViews
#except_on, #hide_on, #initialize_views, #only_on, #post_initialize, #show_on, #show_on_create, #show_on_update, #visible_in_view?
Methods included from Concerns::IsVisible
Methods included from Concerns::HasItemType
#is_card?, #is_collaboration?, #is_field?, #is_header?, #is_heading?, #is_panel?, #is_sidebar?, #is_tab?, #is_tab_group?, #is_tool?
Methods included from Concerns::IsResourceItem
Methods included from Concerns::Hydration
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 89 90 |
# File 'lib/avo/fields/belongs_to_field.rb', line 73 def initialize(id, **args, &block) args[:placeholder] ||= I18n.t("avo.choose_an_option") 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 (readonly)
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 (readonly)
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 (readonly)
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 (readonly)
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 (readonly)
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 (readonly)
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 (readonly)
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)
303 304 305 |
# File 'lib/avo/fields/belongs_to_field.rb', line 303 def can_create?(final_target_resource = target_resource) @can_create && final_target_resource..(:create, raise_exception: false) end |
#database_id ⇒ Object
238 239 240 241 242 243 244 245 |
# File 'lib/avo/fields/belongs_to_field.rb', line 238 def database_id # If the field is a polymorphic value, return the polymorphic_type as key and pre-fill the _id in fill_field. return :"#{polymorphic_as}_type" if polymorphic_as.present? foreign_key rescue attribute_id end |
#database_value ⇒ Object
133 134 135 136 137 |
# File 'lib/avo/fields/belongs_to_field.rb', line 133 def database_value target_resource.id rescue nil end |
#default_name ⇒ Object
277 278 279 280 281 |
# File 'lib/avo/fields/belongs_to_field.rb', line 277 def default_name return polymorphic_as.to_s.humanize if polymorphic_as.present? super end |
#field_label ⇒ Object
What the user sees in the text field
110 111 112 |
# File 'lib/avo/fields/belongs_to_field.rb', line 110 def field_label label end |
#field_value ⇒ Object
The value
103 104 105 106 107 |
# File 'lib/avo/fields/belongs_to_field.rb', line 103 def field_value value.send(database_value) rescue nil end |
#fill_field(record, key, value, params) ⇒ Object
199 200 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 |
# File 'lib/avo/fields/belongs_to_field.rb', line 199 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) # If the type is blank, reset the id too. 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
159 160 161 162 163 164 165 166 167 |
# File 'lib/avo/fields/belongs_to_field.rb', line 159 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 |
#form_field_label ⇒ Object
307 308 309 |
# File 'lib/avo/fields/belongs_to_field.rb', line 307 def form_field_label "#{id}_id" end |
#get_record ⇒ Object
273 274 275 |
# File 'lib/avo/fields/belongs_to_field.rb', line 273 def get_record @record || @resource.record end |
#id_input_foreign_key ⇒ Object
145 146 147 148 149 150 151 |
# File 'lib/avo/fields/belongs_to_field.rb', line 145 def id_input_foreign_key if is_polymorphic? "#{foreign_key}_id" else foreign_key end end |
#index_link_to_record ⇒ Object
291 292 293 294 295 296 297 |
# File 'lib/avo/fields/belongs_to_field.rb', line 291 def index_link_to_record if @link_to_record.present? get_record else value end end |
#index_link_to_resource ⇒ Object
283 284 285 286 287 288 289 |
# File 'lib/avo/fields/belongs_to_field.rb', line 283 def index_link_to_resource if @link_to_record.present? @resource else target_resource end end |
#is_polymorphic? ⇒ Boolean
153 154 155 156 157 |
# File 'lib/avo/fields/belongs_to_field.rb', line 153 def is_polymorphic? polymorphic_as.present? rescue false end |
#label ⇒ Object
186 187 188 189 |
# File 'lib/avo/fields/belongs_to_field.rb', line 186 def label return if target_resource.blank? target_resource.new(record: value)&.record_title end |
#options ⇒ Object
114 115 116 |
# File 'lib/avo/fields/belongs_to_field.rb', line 114 def values_for_type end |
#polymorphic_form_field_label ⇒ Object
311 312 313 |
# File 'lib/avo/fields/belongs_to_field.rb', line 311 def polymorphic_form_field_label "#{id}_type" end |
#reflection ⇒ Object
Get the model reflection instance
176 177 178 179 180 |
# File 'lib/avo/fields/belongs_to_field.rb', line 176 def reflection reflection_for_key(attribute_id) rescue nil end |
#reflection_for_key(key) ⇒ Object
169 170 171 172 173 |
# File 'lib/avo/fields/belongs_to_field.rb', line 169 def reflection_for_key(key) get_model_class(get_record).reflections[key.to_s] rescue nil end |
#relation_model_class ⇒ Object
182 183 184 |
# File 'lib/avo/fields/belongs_to_field.rb', line 182 def relation_model_class @resource.model_class end |
#target_resource(record: @record, polymorphic_model_class: value&.class) ⇒ Object
247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 |
# File 'lib/avo/fields/belongs_to_field.rb', line 247 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.[:class_name].present? get_resource_by_model_class(reflection_object.[:class_name]) else App.get_resource_by_name reflection_key end end end |
#to_permitted_param ⇒ Object
191 192 193 194 195 196 197 |
# File 'lib/avo/fields/belongs_to_field.rb', line 191 def to_permitted_param if polymorphic_as.present? return [:"#{polymorphic_as}_type", :"#{polymorphic_as}_id"] end foreign_key.to_sym end |
#type_input_foreign_key ⇒ Object
139 140 141 142 143 |
# File 'lib/avo/fields/belongs_to_field.rb', line 139 def type_input_foreign_key if is_polymorphic? "#{foreign_key}_type" end end |
#valid_polymorphic_class(possible_class) ⇒ Object
232 233 234 235 236 |
# File 'lib/avo/fields/belongs_to_field.rb', line 232 def valid_polymorphic_class(possible_class) types.find do |type| type.to_s == possible_class.to_s end end |
#value ⇒ Object
92 93 94 95 96 97 98 99 100 |
# File 'lib/avo/fields/belongs_to_field.rb', line 92 def value if is_polymorphic? # Get the value from the pre-filled association record super(polymorphic_as) else # Get the value from the pre-filled association record super(@relation_method) end end |
#values_for_type(model = nil) ⇒ Object
118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/avo/fields/belongs_to_field.rb', line 118 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 || << t("avo.more_records_available") if .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.
318 319 320 321 322 323 324 325 326 327 328 |
# File 'lib/avo/fields/belongs_to_field.rb', line 318 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 |