Module: FlexColumns::Including::IncludeFlexColumns::ClassMethods

Defined in:
lib/flex_columns/including/include_flex_columns.rb

Instance Method Summary collapse

Instance Method Details

#_flex_column_is_included_from(flex_column_name) ⇒ Object

Returns the name of the association from which a flex column of the given name was included.



83
84
85
# File 'lib/flex_columns/including/include_flex_columns.rb', line 83

def _flex_column_is_included_from(flex_column_name)
  @_included_flex_columns_map[flex_column_name]
end

#_flex_columns_include_flex_columns_dynamic_methods_moduleObject

The DynamicMethodsModule on which we define all methods generated by included flex columns.



78
79
80
# File 'lib/flex_columns/including/include_flex_columns.rb', line 78

def _flex_columns_include_flex_columns_dynamic_methods_module
  @_flex_columns_include_flex_columns_dynamic_methods_module ||= FlexColumns::Util::DynamicMethodsModule.new(self, :FlexColumnsIncludedColumnsMethods)
end

#include_flex_columns_from(*args, &block) ⇒ Object

Includes methods from the given flex column or flex columns into this class.

args should be a list of association names from which you want to include columns. It can also end in an options Hash, which can contain:

:prefix

If set, included method names will be prefixed with the given string (followed by an underscore). If not set, the prefix defined on each flex column, if any, will be used; you can override this by explicitly passing nil here.

:visibility

If set to :private, included methods will be marked private, meaning they can only be accessed from inside this model. This can be used to ensure random code across your system can’t directly manipulate flex-column fields.

:delegate

If set to false or nil, then only the method that accesses the flex column itself (above, User#details) will be created; other methods (User#background_color, User#likes_peaches) will not be automatically delegated.



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/flex_columns/including/include_flex_columns.rb', line 101

def include_flex_columns_from(*args, &block)
  # Grab our options, and validate them as necessary...
  options = args.pop if args[-1] && args[-1].kind_of?(Hash)
  options ||= { }

  options.assert_valid_keys(:prefix, :visibility, :delegate)

  case options[:prefix]
  when nil, String, Symbol then nil
  else raise ArgumentError, "Invalid value for :prefix: #{options[:prefix].inspect}"
  end

  unless [ :public, :private, nil ].include?(options[:visibility])
    raise ArgumentError, "Invalid value for :visibility: #{options[:visibility].inspect}"
  end

  unless [ true, false, nil ].include?(options[:delegate])
    raise ArgumentError, "Invalid value for :delegate: #{options[:delegate].inspect}"
  end

  association_names = args

  @_included_flex_columns_map ||= { }

  # Iterate through each association...
  association_names.each do |association_name|
    # Get the association and make sure it's of the right type...
    association = reflect_on_association(association_name.to_sym)
    unless association
      raise ArgumentError, %{You asked #{self.name} to include flex columns from association #{association_name.inspect},
  but this class doesn't seem to have such an association. Associations it has are:

    #{reflect_on_all_associations.map(&:name).sort_by(&:to_s).join(", ")}}
    end

    unless [ :has_one, :belongs_to ].include?(association.macro)
      raise ArgumentError, %{You asked #{self.name} to include flex columns from association #{association_name.inspect},
  but that association is of type #{association.macro.inspect}, not :has_one or :belongs_to.

  We can only include flex columns from an association of these types, because otherwise
  there is no way to know which target object to include the data from.}
    end

    # Grab the target model class, and make sure it has one or more flex columns...
    target_class = association.klass
    if (! target_class.respond_to?(:has_any_flex_columns?)) || (! target_class.has_any_flex_columns?)
      raise ArgumentError, %{You asked #{self.name} to include flex columns from association #{association_name.inspect},
  but the target class of that association, #{association.klass.name}, has no flex columns defined.}
    end

    # Call through and tell those flex columns to create the appropriate methods.
    target_class._all_flex_column_names.each do |flex_column_name|
      @_included_flex_columns_map[flex_column_name] = association_name

      flex_column_class = target_class._flex_column_class_for(flex_column_name)
      flex_column_class.include_fields_into(_flex_columns_include_flex_columns_dynamic_methods_module, association_name, self, options)
    end
  end
end