module FlexColumns::HasFlexColumns::ClassMethods

Public Instance Methods

_all_flex_column_names() click to toggle source

What are the names of all flex columns defined on this model?

# File lib/flex_columns/has_flex_columns.rb, line 152
def _all_flex_column_names
  _flex_column_classes.map(&:column_name)
end
_flex_column_class_for(flex_column_name) click to toggle source

Given the name of a flex column, returns the flex-column class for that column. Raises FlexColumns::Errors::NoSuchColumnError if there is no column with the given name.

# File lib/flex_columns/has_flex_columns.rb, line 169
      def _flex_column_class_for(flex_column_name)
        flex_column_name = _flex_column_normalize_name(flex_column_name)
        out = _flex_column_classes.detect { |fcc| fcc.column_name == flex_column_name }

        unless out
          raise FlexColumns::Errors::NoSuchColumnError, %{Model class #{self.name} has no flex column named #{flex_column_name.inspect};
it has flex columns named: #{_all_flex_column_names.sort_by(&:to_s).inspect}.}
        end

        out
      end
_flex_column_dynamic_methods_module() click to toggle source

Returns the DynamicMethodsModule that we add methods to that should be present on this model class.

# File lib/flex_columns/has_flex_columns.rb, line 182
def _flex_column_dynamic_methods_module
  @_flex_column_dynamic_methods_module ||= FlexColumns::Util::DynamicMethodsModule.new(self, :FlexColumnsDynamicMethods)
end
_flex_column_normalize_name(flex_column_name) click to toggle source

Normalizes the name of a flex column, so we’re consistent when using it for things like hash keys, no matter how the client specifies it to us.

# File lib/flex_columns/has_flex_columns.rb, line 163
def _flex_column_normalize_name(flex_column_name)
  flex_column_name.to_s.strip.downcase.to_sym
end
_flex_columns_redefine_all_methods!() click to toggle source

Defines, or redefines, all methods on the dynamic-methods module associated with this model. This gets called whenever we define a new flex column, or if you call .reset_column_information on the associated model.

# File lib/flex_columns/has_flex_columns.rb, line 207
def _flex_columns_redefine_all_methods!
  _flex_column_dynamic_methods_module.remove_all_methods!
  _flex_column_classes.each(&:sync_methods!)
end
_has_flex_column_named?(column_name) click to toggle source

Does this model have a flex column with the given name?

# File lib/flex_columns/has_flex_columns.rb, line 157
def _has_flex_column_named?(column_name)
  _all_flex_column_names.include?(_flex_column_normalize_name(column_name))
end
create_flex_object_from(column_name, raw_string) click to toggle source

Exactly like create_flex_objects_from, except that instead of taking an Array of raw strings and returning an Array of flex-column objects, takes a single raw string and returns a single flex-column object.

create_flex_objects_from is currently very slightly faster than simply calling this method in a loop; however, in the future, the difference in performance may increase. If you have more than one string to create a flex-column object from, you should definitely use create_flex_objects_from instead of this method.

# File lib/flex_columns/has_flex_columns.rb, line 218
def create_flex_object_from(column_name, raw_string)
  _flex_column_class_for(column_name).new(raw_string)
end
create_flex_objects_from(column_name, raw_strings) click to toggle source

Given the name of a column in column_name and an Array of (possibly nil) JSON-formatted strings (which can also be compressed using the flex_columns compression mechanism), returns an Array of new flex-column objects for that column that are not attached to any particular model instance. These objects will obey all field-definition rules for that column, be able to validate themselves (if you call valid? on them), retrieve data, have any custom methods defined on them that you defined on that flex column, and so on.

However, because they’re detached from any model instance, they also won’t save themselves to the database under any circumstances; you are responsible for calling to_stored_data on them, and getting those strings into the database in the right places yourself, if you want to save them.

The purpose of this method is to allow you to use flex_columns in bulk-access situations, such as when you’ve selected many records from the database without using ActiveRecord, for performance reasons (e.g., User.connection.select_all("...")).

# File lib/flex_columns/has_flex_columns.rb, line 235
def create_flex_objects_from(column_name, raw_strings)
  column_class = _flex_column_class_for(column_name)
  raw_strings.map do |rs|
    column_class.new(rs)
  end
end
flex_column(flex_column_name, options = { }, &block) click to toggle source

Declares a new flex column. flex_column_name is its name; options is passed through to FlexColumns::Definition::FlexColumnContentsClass#setup!, and so can contain any of the options that that method accepts. The block, if passed, will be evaluated in the context of the generated class.

# File lib/flex_columns/has_flex_columns.rb, line 189
def flex_column(flex_column_name, options = { }, &block)
  flex_column_name = _flex_column_normalize_name(flex_column_name)

  new_class = Class.new(FlexColumns::Contents::FlexColumnContentsBase)
  new_class.setup!(self, flex_column_name, options, &block)

  _flex_column_classes.delete_if { |fcc| fcc.column_name == flex_column_name }
  _flex_column_classes << new_class

  define_method(flex_column_name) do
    _flex_column_object_for(flex_column_name)
  end

  _flex_columns_redefine_all_methods!
end
has_any_flex_columns?() click to toggle source

Does this class have any flex columns? If this module has been included into a class, then the answer is true.

# File lib/flex_columns/has_flex_columns.rb, line 147
def has_any_flex_columns?
  true
end
reset_column_information_with_flex_columns() click to toggle source
# File lib/flex_columns/has_flex_columns.rb, line 140
def reset_column_information_with_flex_columns
  reset_column_information_without_flex_columns
  _flex_column_classes.each { |c| c.reset_column_information }
  _flex_columns_redefine_all_methods!
end

Private Instance Methods

_flex_column_classes() click to toggle source

Returns the set of currently-active flex-column classes – that is, classes that inherit from FlexColumns::Contents::FlexColumnContentsBase and represent our declared flex columns. We say “currently active” because declaring a new flex column with the same name as a previous one will replace its class in this list.

This is an Array instead of a Hash because the order in which we sync methods to the dynamic-methods module matters: flex columns declared later should have any delegate methods they declare supersede any methods from flex columns declared previously. While Ruby >= 1.9 has ordered Hashes, which means we could use it here, we still support Ruby 1.8, and so need the ordering that an Array gives us.

# File lib/flex_columns/has_flex_columns.rb, line 251
def _flex_column_classes
  @_flex_column_classes ||= [ ]
end