Module: Acts::DataTable::MultiColumnScopes::ClassMethods

Defined in:
lib/acts_as_data_table/multi_column_scopes.rb

Instance Method Summary collapse

Instance Method Details

#has_multi_column_scope(scope_name, *args) ⇒ Object

Generates a scope to search for a given string in multiple columns at once. Columns may either be in the own table or in associated tables. It also automatically generates concat queries to enable full name searches, e.g. for a users table with separate columns for first and last name (see examples below)

The result can be used further to chain the query like every other scope

If the last argument is a Hash, it will be used as options.

The method does currently not support chained includes, this will be added in the future (e.g. :user_rooms => => :number)

Examples:

Basic usage, searching in two columns

has_multi_column_scope :email_or_name, :email, :name

Searching for a full name by concatenating two columns

has_multi_column_scope :email_or_name, :email, [:first_name, :last_name]

Including an association named :title (belongs_to :title)

has_multi_column_scope :name_or_title, [:first_name, :last_name], {:title => :name}, {}
#The empty has at the end is necessary as otherwise the title-hash would
#be taken as options.

Parameters:

  • scope_name (String, Symbol)

    The newly generated scope’s name, e.g. :full_text

  • options (Hash)

    a customizable set of options



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/acts_as_data_table/multi_column_scopes.rb', line 44

def has_multi_column_scope(scope_name, *args)
  options = {:downcase => true}
  options.merge!(args.pop) if args.size > 1 && args.last.is_a?(Hash)

  include_chain = []

  fields        = args.map {|arg| Acts::DataTable::MultiColumnScopes.process_column_arg(arg, include_chain, self)}
  fields        = fields.flatten.map {|f| Acts::DataTable::MultiColumnScopes.database_cast(f)}
  fields        = fields.map {|f| "LOWER(#{f})"} if options[:downcase]

  conditions    = fields.map {|f| "#{f} LIKE ?"}.join(' OR ')
  include_chain = include_chain.uniq.compact

  named_scope scope_name, lambda {|search|
    if search.present?
      s = "%#{search}%"
      s = s.downcase if options[:downcase]
      { :include => include_chain, :conditions => [conditions] + Array.new(fields.size, s) }
    else
      {}
    end
  }
end