Module: FlexColumns::HasFlexColumns

Extended by:
ActiveSupport::Concern
Defined in:
lib/flex_columns/has_flex_columns.rb

Overview

HasFlexColumns is the module that gets included in an ActiveRecord model class as soon as it declares a flex column (using FlexColumns::ActiveRecord::Base#flex_column). While most of the actual work of maintaining and working with a flex column is accomplished by the FlexColumns::Definition::FlexColumnContentsClass module and the FlexColumns::Contents::FlexColumnContentsBase class, there remains, nevertheless, some important work to do here.

Defined Under Namespace

Modules: ClassMethods

Instance Method Summary collapse

Instance Method Details

#_flex_column_object_for(column_name, create_if_needed = true) ⇒ Object

Returns the correct flex-column object for the given column name. This simply creates an instance of the appropriate flex-column class, and saves it away so it will be returned again if someone requests the object for the same column later.



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/flex_columns/has_flex_columns.rb', line 48

def _flex_column_object_for(column_name, create_if_needed = true)
  # It's possible to end up with two copies of this method on a class, if that class both has a flex column of its
  # own _and_ includes one via FlexColumns::Including::IncludeFlexColumns#include_flex_columns_from. If so, we want
  # each method to defer to the other one, so that both will work.
  begin
    return super(column_name)
  rescue NoMethodError
    # ok
  rescue FlexColumns::Errors::NoSuchColumnError
    # ok
  end

  column_name = self.class._flex_column_normalize_name(column_name)

  out = _flex_column_objects[column_name]
  if (! out) && create_if_needed
    out = _flex_column_objects[column_name] = self.class._flex_column_class_for(column_name).new(self)
  end
  out
end

#_flex_columns_before_save!Object

Before we save this model, make sure each flex column has a chance to serialize itself up and assign itself properly to this model object. Note that we only need to call through to flex-column objects that have actually been instantiated, since, by definition, there’s no way the contents of any other flex columns could possibly have been changed.



26
27
28
29
30
31
32
33
# File 'lib/flex_columns/has_flex_columns.rb', line 26

def _flex_columns_before_save!
  self.class._all_flex_column_names.each do |flex_column_name|
    klass = self.class._flex_column_class_for(flex_column_name)
    if klass.requires_serialization_on_save?(self)
      _flex_column_object_for(flex_column_name).before_save!
    end
  end
end

#_flex_columns_before_validation!Object

Before we validate this model, make sure each flex column has a chance to run its validations and propagate any errors back to this model. Note that we need to call through to any flex-column object that has a validation defined, since we want to comply with Rails’ validation strategy: validations run whenever you save an object, whether you’ve changed that particular attribute or not.



39
40
41
42
43
# File 'lib/flex_columns/has_flex_columns.rb', line 39

def _flex_columns_before_validation!
  _all_present_flex_column_objects.each do |flex_column_object|
    flex_column_object.before_validation! if flex_column_object.touched?
  end
end

#reload(*args) ⇒ Object

When you reload a model object, we should reload its flex-column objects, too.



70
71
72
73
# File 'lib/flex_columns/has_flex_columns.rb', line 70

def reload(*args)
  super(*args)
  @_flex_column_objects = { }
end