module FlexColumns::HasFlexColumns::ClassMethods
Public Instance Methods
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
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
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
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
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
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
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
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
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
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
# 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
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