class ScopedSearch::Definition::Field

The Field class specifies a field of a model that is available for searching, in what cases this field should be searched and its default search behavior.

Instances of this class are created when calling scoped_search in your model class, so you should not create instances of this class yourself.

Attributes

complete_enabled[R]
complete_value[R]
definition[R]
ext_method[R]
field[R]
key_field[R]
key_relation[R]
offset[R]
only_explicit[R]
operators[R]
relation[R]
validator[R]
word_size[R]

Public Class Methods

new(definition, field = nil, aliases: [], complete_enabled: true, complete_value: nil, default_operator: nil, default_order: nil, ext_method: nil, full_text_search: nil, in_key: nil, offset: nil, on: field, on_key: nil, only_explicit: nil, operators: nil, profile: nil, relation: nil, rename: nil, validator: nil, word_size: 1, **kwargs) click to toggle source

Initializes a Field instance given the definition passed to the scoped_search call on the ActiveRecord-based model class.

Field name may be given in positional 'field' argument or 'on' named argument.

# File lib/scoped_search/definition.rb, line 27
def initialize(definition,
               field = nil,
               aliases: [],
               complete_enabled: true,
               complete_value: nil,
               default_operator: nil,
               default_order: nil,
               ext_method: nil,
               full_text_search: nil,
               in_key: nil,
               offset: nil,
               on: field,
               on_key: nil,
               only_explicit: nil,
               operators: nil,
               profile: nil,
               relation: nil,
               rename: nil,
               validator: nil,
               word_size: 1,
               **kwargs)

  # Prefer 'on' kw arg if given, defaults to the 'field' positional to allow either syntax
  raise ArgumentError, "Missing field or 'on' keyword argument" if on.nil?
  @field = on.to_sym

  # Reserved Ruby keywords so access via kwargs instead, but deprecate them for future versions
  if kwargs.key?(:in)
    relation = kwargs.delete(:in)
    ActiveSupport::Deprecation.warn("'in' argument deprecated, prefer 'relation' since scoped_search 4.0.0", caller(6))
  end
  if kwargs.key?(:alias)
    aliases += [kwargs.delete(:alias)]
    ActiveSupport::Deprecation.warn("'alias' argument deprecated, prefer aliases: [..] since scoped_search 4.0.0", caller(6))
  end
  raise ArgumentError, "Unknown arguments to scoped_search: #{kwargs.keys.join(', ')}" unless kwargs.empty?

  @definition = definition
  @definition.profile = profile if profile
  @definition.default_order ||= generate_default_order(default_order, rename || @field) if default_order

  # Set attributes from keyword arguments
  @complete_enabled = complete_enabled
  @complete_value   = complete_value
  @default_operator = default_operator
  @ext_method       = ext_method
  @full_text_search = full_text_search
  @key_field        = on_key
  @key_relation     = in_key
  @offset           = offset
  @only_explicit    = !!only_explicit
  @operators        = operators
  @relation         = relation
  @validator        = validator
  @word_size        = word_size

  # Store this field in the field array
  definition.define_field(rename || @field, self)

  # Store definition for aliases as well
  aliases.each { |al| definition.define_field(al, self) }
end

Public Instance Methods

column() click to toggle source

Returns the ActiveRecord column definition that corresponds to this field.

# File lib/scoped_search/definition.rb, line 111
def column
  @column ||= begin
    if klass.columns_hash.has_key?(field.to_s)
      klass.columns_hash[field.to_s]
    else
      raise ActiveRecord::UnknownAttributeError.new(klass, field)
    end
  end
end
date?() click to toggle source

Returns true if this field is a date-like column

# File lib/scoped_search/definition.rb, line 132
def date?
  type == :date
end
datetime?() click to toggle source

Returns true if this field is a datetime-like column

# File lib/scoped_search/definition.rb, line 127
def datetime?
  [:datetime, :time, :timestamp].include?(type)
end
default_operator() click to toggle source

Returns the default search operator for this field.

# File lib/scoped_search/definition.rb, line 158
def default_operator
  @default_operator ||= case type
    when :string, :text then :like
    else :eq
  end
end
generate_default_order(default_order, field) click to toggle source
# File lib/scoped_search/definition.rb, line 165
def generate_default_order(default_order, field)
  order = (default_order.to_s.downcase.include?('desc')) ? "DESC" : "ASC"
  return "#{field} #{order}"
end
key_klass() click to toggle source

The ActiveRecord-based class that belongs the key field in a key-value pair.

# File lib/scoped_search/definition.rb, line 100
def key_klass
  @key_klass ||= if key_relation
    definition.reflection_by_name(definition.klass, key_relation).klass
  elsif relation
    definition.reflection_by_name(definition.klass, relation).klass
  else
    definition.klass
  end
end
klass() click to toggle source

The ActiveRecord-based class that belongs to this field.

# File lib/scoped_search/definition.rb, line 91
def klass
  @klass ||= if relation
    definition.reflection_by_name(definition.klass, relation).klass
  else
    definition.klass
  end
end
numerical?() click to toggle source

Returns true if this field is numerical. Numerical means either integer, floating point or fixed point.

# File lib/scoped_search/definition.rb, line 143
def numerical?
  [:integer, :double, :float, :decimal].include?(type)
end
quoted_field() click to toggle source

Return 'table'.'column' with the correct database quotes

# File lib/scoped_search/definition.rb, line 171
def quoted_field
  c = klass.connection
  "#{c.quote_table_name(klass.table_name)}.#{c.quote_column_name(field)}"
end
set?() click to toggle source

Returns true if this is a set.

# File lib/scoped_search/definition.rb, line 153
def set?
  complete_value.is_a?(Hash)
end
temporal?() click to toggle source

Returns true if this field is a date or datetime-like column.

# File lib/scoped_search/definition.rb, line 137
def temporal?
  datetime? || date?
end
textual?() click to toggle source

Returns true if this is a textual column.

# File lib/scoped_search/definition.rb, line 148
def textual?
  [:string, :text].include?(type)
end
type() click to toggle source

Returns the column type of this field.

# File lib/scoped_search/definition.rb, line 122
def type
  @type ||= column.type
end