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"})


60
61
62
63
64
65
# File 'lib/searchlogic/search.rb', line 60

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)



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
160
161
162
163
164
165
166
167
168
169
170
171
172
# File 'lib/searchlogic/search.rb', line 122

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.



72
73
74
# File 'lib/searchlogic/search.rb', line 72

def conditions
  @conditions
end

#current_scopeObject

Returns the value of attribute current_scope.



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

def current_scope
  @current_scope
end

#klassObject

Returns the value of attribute klass.



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

def klass
  @klass
end

Instance Method Details

#cloneObject



67
68
69
# File 'lib/searchlogic/search.rb', line 67

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.



108
109
110
111
112
113
114
# File 'lib/searchlogic/search.rb', line 108

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

#do_searchObject



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

def do_search
  @current_scope
end

#ordering_byObject

Returns the column we are currently ordering by



117
118
119
# File 'lib/searchlogic/search.rb', line 117

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

#respond_to?(method_name) ⇒ Boolean

Returns:

  • (Boolean)


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

def respond_to?(method_name)
  begin
    send method_name
    true
  rescue NameError
    false
  end
end