module IgnorableColumns::ClassMethods

Public Instance Methods

ignore_column(*cols)
Alias for: ignore_columns
ignore_column_in_sql()
ignore_columns(*cols) click to toggle source

Prevent Rails from loading a table column. Useful for legacy database schemas with problematic column names, like 'class' or 'attributes'.

class Topic < ActiveRecord::Base
  ignore_columns :attributes, :class
end

Topic.new.respond_to?(:attributes) => false
# File lib/ignorable_columns.rb, line 33
def ignore_columns(*cols)
  self.ignorable_columns ||= []
  self.ignorable_columns += (cols || []).map(&:to_s)
  self.ignorable_columns.tap(&:uniq!)
  reset_columns
  columns
end
Also aliased as: ignore_column
ignore_columns_in_sql() click to toggle source

Ignore columns for select statements. Useful for optimizing queries that load large amounts of rarely data. Exclude ignored columns from the sql queries. NOTE: should be called after ignore_columns

class Topic < ActiveRecord::Base
  ignore_columns :attributes, :class
  ignore_columns_in_sql
end
# File lib/ignorable_columns.rb, line 51
def ignore_columns_in_sql
  (self.default_scopes = orig_default_scopes) && return unless ignorable_columns.present?
  unless default_scopes.include? default_scopes_cache[ignorable_columns]
    default_scopes_cache[ignorable_columns] ||= proc { select(*(all_columns.map(&:name) - ignorable_columns)) }
    self.default_scopes = (default_scopes.clone || []) << default_scopes_cache[ignorable_columns]
  end
end
Also aliased as: ignore_column_in_sql
ignored_column?(column) click to toggle source

Has a column been ignored? Accepts both ActiveRecord::ConnectionAdapter::Column objects, and actual column names ('title')

# File lib/ignorable_columns.rb, line 63
def ignored_column?(column)
  self.ignorable_columns.present? && self.ignorable_columns.include?(
    column.respond_to?(:name) ? column.name : column.to_s
  )
end
including_ignored_columns(*cols) click to toggle source

Execute block in a scope including all or some of the ignored columns. If no arguments are passed all ignored columns will be included, otherwise only the subset passed as argument will be included.

class Topic < ActiveRecord::Base
  ignore_columns :attributes, :class
  ignore_columns_in_sql
end
...
Topic.including_ignored_columns { Topic.last(5).map(&:attributes) }
Topic.including_ignored_columns(:class) { Topic.last(5).map(&:attributes) }
# File lib/ignorable_columns.rb, line 80
def including_ignored_columns(*cols)
  st_cols = cols.map(&:to_s)
  sy_cols = cols.map(&:to_sym)
  if including_columns_subclass_cache[sy_cols].present?
    return including_columns_subclass_cache[sy_cols]
  else
    subclass_name = including_ignored_columns_subclass_name(st_cols)
    begin
      including_columns_subclass_cache[sy_cols] = Object.const_get(subclass_name)
      return including_columns_subclass_cache[sy_cols]
    rescue NameError
      including_columns_subclass_cache[sy_cols] = generate_subclass_for_ignored_cols(subclass_name, st_cols)
    end
  end
end
including_ignored_columns_subclass_name(cols = nil) click to toggle source
# File lib/ignorable_columns.rb, line 127
def including_ignored_columns_subclass_name(cols = nil)
  subclass_name = name + 'With'
  subclass_name += if cols.present?
                     cols.sort.map(&:camelcase).join
                   else
                     'All'
                   end
  subclass_name
end
reset_ignorable_columns() click to toggle source
# File lib/ignorable_columns.rb, line 122
def reset_ignorable_columns
  reset_columns
  self.default_scopes = orig_default_scopes
end

Private Instance Methods

all_column_names() click to toggle source
# File lib/ignorable_columns.rb, line 164
def all_column_names
  column_names unless @all_column_names
  @all_column_names
end
all_columns() click to toggle source
# File lib/ignorable_columns.rb, line 159
def all_columns
  columns unless @all_columns
  @all_columns
end
default_scopes_cache() click to toggle source
# File lib/ignorable_columns.rb, line 155
def default_scopes_cache
  @default_scopes_cache ||= {}
end
generate_subclass_for_ignored_cols(name, st_cols) click to toggle source
# File lib/ignorable_columns.rb, line 139
def generate_subclass_for_ignored_cols(name, st_cols)
  new_subclass = Object.const_set(name, Class.new(self))
  temp_ignorable_columns = st_cols.present? ? ignorable_columns - st_cols : []

  new_subclass.reset_ignorable_columns
  new_subclass.ignorable_columns = temp_ignorable_columns
  new_subclass.default_scopes = orig_default_scopes
  new_subclass.ignore_columns_in_sql if default_scopes != orig_default_scopes

  new_subclass
end
including_columns_subclass_cache() click to toggle source
# File lib/ignorable_columns.rb, line 151
def including_columns_subclass_cache
  @including_columns_subclass_cache ||= {}
end
init_columns(col_names = nil) click to toggle source
# File lib/ignorable_columns.rb, line 173
def init_columns(col_names = nil)
  reset_columns
  @columns = col_names.nil? ? all_columns : all_columns.select { |c| col_names.include? c.name }
  @column_names = col_names.nil? ? all_column_names : all_column_names.select { |cn| col_names.include? cn }
end
orig_default_scopes() click to toggle source
# File lib/ignorable_columns.rb, line 169
def orig_default_scopes
  default_scopes - default_scopes_cache.values
end
reset_columns() click to toggle source
# File lib/ignorable_columns.rb, line 179
def reset_columns
  reset_column_information
  descendants.each(&:reset_column_information)
  @columns = nil
  @column_names = nil
end