Class: Searchlogic::Search

Inherits:
Object
  • Object
show all
Defined in:
lib/searchlogic/search.rb

Overview

A class that acts like a model, creates attr_accessors for named_scopes, and then chains together everything when an “action” method is called. It basically makes implementing search forms in your application effortless:

search = User.search
search.username_like = "bjohnson"
search.all

Is equivalent to:

User.search(:username_like => "bjohnson").all

Is equivalent to:

User.username_like("bjohnson").all

Defined Under Namespace

Modules: Implementation Classes: UnknownConditionError

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(klass, current_scope, conditions = {}) ⇒ Search

Creates a new search object for the given class. Ex:

Searchlogic::Search.new(User, {}, {:username_like => "bjohnson"})


47
48
49
50
51
52
# File 'lib/searchlogic/search.rb', line 47

def initialize(klass, current_scope, conditions = {})
  self.klass = klass
  self.current_scope = current_scope
  @conditions ||= {}
  self.conditions = conditions if conditions.is_a?(Hash)
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args, &block) ⇒ Object (private)



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
# File 'lib/searchlogic/search.rb', line 106

def method_missing(name, *args, &block)
  condition_name = condition_name(name)
  scope_name = scope_name(condition_name)
  
  if setter?(name)
    if scope?(scope_name)
      if args.size == 1
        write_condition(
          condition_name,
          type_cast(
            args.first,
            cast_type(scope_name),
            scope_options(scope_name).respond_to?(:searchlogic_options) ? scope_options(scope_name).searchlogic_options : {}
          )
        )
      else
        write_condition(condition_name, args)
      end
    else
      raise UnknownConditionError.new(condition_name)
    end
  elsif scope?(scope_name) && args.size <= 1
    if args.size == 0
      read_condition(condition_name)
    else
      send("#{condition_name}=", *args)
      self
    end
  else
    scope = conditions_array.inject(klass.scoped(current_scope) || {}) do |scope, condition|
      scope_name, value = condition
      scope_name = normalize_scope_name(scope_name)
      klass.send(scope_name, value) if !klass.respond_to?(scope_name)
      arity = klass.named_scope_arity(scope_name)
      
      if !arity || arity == 0
        if value == true
          scope.send(scope_name)
        else
          scope
        end
      elsif arity == -1
        scope.send(scope_name, *(value.is_a?(Array) ? value : [value]))
      else
        scope.send(scope_name, value)
      end
    end
    scope.send(name, *args, &block)
  end
end

Instance Attribute Details

#conditionsObject

Returns a hash of the current conditions set.



59
60
61
# File 'lib/searchlogic/search.rb', line 59

def conditions
  @conditions
end

#current_scopeObject

Returns the value of attribute current_scope.



41
42
43
# File 'lib/searchlogic/search.rb', line 41

def current_scope
  @current_scope
end

#klassObject

Returns the value of attribute klass.



41
42
43
# File 'lib/searchlogic/search.rb', line 41

def klass
  @klass
end

Instance Method Details

#cloneObject



54
55
56
# File 'lib/searchlogic/search.rb', line 54

def clone
  self.class.new(klass, current_scope && current_scope.clone, conditions.clone)
end

#delete(*names) ⇒ Object

Delete a condition from the search. Since conditions map to named scopes, if a named scope accepts a parameter there is no way to actually delete the scope if you do not want it anymore. A nil value might be meaningful to that scope.



92
93
94
95
96
97
98
# File 'lib/searchlogic/search.rb', line 92

def delete(*names)
  names.each do |name|
    @conditions.delete(name.to_sym)
    mass_conditions.delete(name)
  end
  self
end

#ordering_byObject

Returns the column we are currently ordering by



101
102
103
# File 'lib/searchlogic/search.rb', line 101

def ordering_by
  order && order.to_s.gsub(/^(ascend|descend)_by_/, '')
end