Class: Binda::FieldSetting
- Inherits:
-
ApplicationRecord
- Object
- ActiveRecord::Base
- ApplicationRecord
- Binda::FieldSetting
- Extended by:
- FriendlyId
- Defined in:
- app/models/binda/field_setting.rb
Class Method Summary collapse
-
.get_field_classes ⇒ Object
An array of all classes which represent fields associated to Binda::FieldSetting This definition must stay on the top of the file.
-
.get_id(field_slug) ⇒ integer
Retrieve the ID if a slug is provided and update the field_settings_array in order to avoid calling the database (or the cached response) every time.
-
.reset_field_settings_array ⇒ null
Reset the field_settings_array.
Instance Method Summary collapse
-
#add_choice_if_allow_null_is_false ⇒ Object
Validation method that check if the current
Binda::Selectioninstance has at least a choice before updating allow null to false. -
#check_allow_null_for_radio ⇒ Object
It makes sure radio buttons have allow_null set to false.
-
#check_allow_null_option ⇒ Object
Check
allow_nulloption. -
#convert_allow_null__nil_to_false ⇒ Object
Make sure that allow_null is set to false instead of nil.
- #create_field_instance_for(instance) ⇒ Object
-
#create_field_instances ⇒ Object
Generates a default field instances for each existing component or board which is associated to that field setting.
-
#create_field_instances_for_instance(instance, field_class, field_setting_id) ⇒ Object
Helper for create_field_instances method.
-
#default_slug ⇒ Object
Set slug name.
-
#is_rejected(attributes) ⇒ Object
Sets the validation rules to accept and save an attribute.
-
#should_generate_new_friendly_id? ⇒ Boolean
Friendly id preference on slug generation.
-
#slug_uniqueness ⇒ Object
Check slug uniqueness.
-
#structure ⇒ ActiveRecord
Get the structure of the field group to which the field setting belongs.
-
#structures ⇒ ActiveRecord::Relation
Get structure on which the current field setting is attached.
Class Method Details
.get_field_classes ⇒ Object
An array of all classes which represent fields associated to Binda::FieldSetting This definition must stay on the top of the file
8 9 10 |
# File 'app/models/binda/field_setting.rb', line 8 def self.get_field_classes %w( String Text Date Image Video Repeater Radio Selection Checkbox Relation ) end |
.get_id(field_slug) ⇒ integer
Retrieve the ID if a slug is provided and update the field_settings_array
in order to avoid calling the database (or the cached response) every time.
This should speed up requests and make Rails logs are cleaner.
191 192 193 194 195 196 197 198 199 |
# File 'app/models/binda/field_setting.rb', line 191 def self.get_id(field_slug) # Get field setting id from slug, without multiple calls to database # (the query runs once and caches the result, then any further call uses the cached result) @@field_settings_array = self.pluck(:slug, :id) if @@field_settings_array.nil? selected_field_setting = @@field_settings_array.select{ |fs| fs[0] == field_slug }[0] raise ArgumentError, "There isn't any field setting with the current slug \"#{field_slug}\".", caller if selected_field_setting.nil? id = selected_field_setting[1] return id end |
.reset_field_settings_array ⇒ null
Reset the field_settings_array. It’s called every time
the user creates or destroyes a Binda::FieldSetting
205 206 207 208 209 210 |
# File 'app/models/binda/field_setting.rb', line 205 def self.reset_field_settings_array # Reset the result of the query taken with the above method, # this is needed when a user creates a new field_setting but # `get_field_setting_id` has already run once @@field_settings_array = nil end |
Instance Method Details
#add_choice_if_allow_null_is_false ⇒ Object
Validation method that check if the current Binda::Selection instance has at least a choice before
updating allow null to false
293 294 295 296 297 298 299 300 301 302 303 304 305 |
# File 'app/models/binda/field_setting.rb', line 293 def add_choice_if_allow_null_is_false if %(selection radio checkbox).include?(self.field_type) && !self.allow_null? if self.choices.empty? # Add a choice if there is none, it will be automatically assign as default choice self.choices.create!(label: I18n.t("binda.choice.default_label"), value: I18n.t("binda.choice.default_value")) elsif self.default_choice_id.nil? # Assign a choice as default one if there is any # REVIEW there is some deprecation going on, but I'm not sure i directly involves the `update` method self.update!(default_choice_id: self.choices.first.id) end end end |
#check_allow_null_for_radio ⇒ Object
It makes sure radio buttons have allow_null set to false.
175 176 177 178 179 180 |
# File 'app/models/binda/field_setting.rb', line 175 def check_allow_null_for_radio if field_type == 'radio' && allow_null? self.allow_null = false warn "WARNING: it's not possible that a field setting with type `radio` has allow_null=true." end end |
#check_allow_null_option ⇒ Object
Check allow_null option
Creating a selection with allow_null set to false will automatically generate a critical error.
This is due to the fact that 1) there is no choice to select, but 2) the selection field must have at least one.
The error can be easily removed by assigning a choice to the current field setting.
This method is preferred to a validation because it allows to remove all choices before adding new ones.
286 287 288 289 |
# File 'app/models/binda/field_setting.rb', line 286 def check_allow_null_option return if self.allow_null? Selection.check_all_selections_depending_on(self) end |
#convert_allow_null__nil_to_false ⇒ Object
Make sure that allow_null is set to false instead of nil.
(This isn't done with a database constraint in order to gain flexibility)
REVIEW: not sure what flexibility is needed. Maybe should be done differently
216 217 218 |
# File 'app/models/binda/field_setting.rb', line 216 def convert_allow_null__nil_to_false self.allow_null = false if self.allow_null.nil? end |
#create_field_instance_for(instance) ⇒ Object
259 260 261 262 263 264 265 266 267 |
# File 'app/models/binda/field_setting.rb', line 259 def create_field_instance_for(instance) if self.is_root? create_field_instances_for_instance(instance, field_class, self.id) else instance.repeaters.select{|r| r.field_setting_id == self.parent_id}.each do |repeater| create_field_instances_for_instance(repeater, field_class, self.id) end end end |
#create_field_instances ⇒ Object
Generates a default field instances for each existing component or board
which is associated to that field setting. This avoid having issues
with Binda::FieldSetting.get_id method which would throw an ambiguous error
that there isn't any field setting associated when infact it's
the actual field missing, not the field setting itself.
A similar script runs after saving components and boards which makes sure
a field instance is always present no matter if the component has been created
before the field setting or the other way around.
249 250 251 252 253 254 255 256 257 |
# File 'app/models/binda/field_setting.rb', line 249 def create_field_instances # Get the structure structure = self.structures.includes(:board, components: [:repeaters]).first field_class = "Binda::#{self.field_type.classify}" structure.components.each do |component| create_field_instances_for_instance(component, field_class, self.id) end create_field_instances_for_instance(structure.board, field_class, self.id) if structure.board.present? end |
#create_field_instances_for_instance(instance, field_class, field_setting_id) ⇒ Object
Helper for create_field_instances method
270 271 272 273 274 275 276 |
# File 'app/models/binda/field_setting.rb', line 270 def create_field_instances_for_instance(instance, field_class, field_setting_id) field_class.constantize.find_or_create_by!( field_setting_id: field_setting_id, fieldable_id: instance.id, fieldable_type: instance.class.name ) end |
#default_slug ⇒ Object
Set slug name
It generates 4 possible slugs before falling back to FriendlyId default behaviour
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
# File 'app/models/binda/field_setting.rb', line 146 def default_slug slug = '' slug << self.field_group.structure.name slug << '-' slug << self.field_group.name unless self.parent.nil? slug << '-' slug << self.parent.name end return [ "#{ slug }--#{ self.name }", "#{ slug }--#{ self.name }-1", "#{ slug }--#{ self.name }-2", "#{ slug }--#{ self.name }-3" ] end |
#is_rejected(attributes) ⇒ Object
Sets the validation rules to accept and save an attribute
66 67 68 |
# File 'app/models/binda/field_setting.rb', line 66 def is_rejected( attributes ) attributes['label'].blank? || attributes['content'].blank? end |
#should_generate_new_friendly_id? ⇒ Boolean
Friendly id preference on slug generation
Method inherited from friendly id
139 140 141 |
# File 'app/models/binda/field_setting.rb', line 139 def should_generate_new_friendly_id? slug.blank? end |
#slug_uniqueness ⇒ Object
Check slug uniqueness
164 165 166 167 168 169 170 171 172 |
# File 'app/models/binda/field_setting.rb', line 164 def slug_uniqueness record_with_same_slug = self.class.where(slug: slug) if record_with_same_slug.any? && !record_with_same_slug.ids.include?(id) errors.add(:slug, I18n.t("binda.field_setting.validation_message.slug", { arg1: slug })) return false else return true end end |
#structure ⇒ ActiveRecord
Get the structure of the field group to which the field setting belongs.
236 237 238 |
# File 'app/models/binda/field_setting.rb', line 236 def structure self.structures.first end |
#structures ⇒ ActiveRecord::Relation
Get structure on which the current field setting is attached. It should be one, but in order to
be able to add other methods to the query this methods returns a `ActiveRecord::Relation` object, not
a `ActiveRecord`
225 226 227 228 229 230 231 |
# File 'app/models/binda/field_setting.rb', line 225 def structures Structure.left_outer_joins( field_groups: [:field_settings] ).where( binda_field_settings: { id: self.id } ) end |