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

def initialize(klass, current_scope, conditions = {})
  self.klass = klass
  self.current_scope = current_scope
  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)



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/searchlogic/search.rb', line 81

def method_missing(name, *args, &block)
  if name.to_s =~ /(\w+)=$/
    condition = $1.to_sym
    scope_name = normalize_scope_name($1)
    if scope?(scope_name)
      conditions[condition] = type_cast(args.first, cast_type(scope_name))
    else
      raise UnknownConditionError.new(name)
    end
  elsif scope?(normalize_scope_name(name))
    if args.size > 0
      send("#{name}=", *args)
      self
    else
      conditions[name]
    end
  else
    scope = conditions.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
      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.



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

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



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

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.



75
76
77
78
# File 'lib/searchlogic/search.rb', line 75

def delete(*names)
  names.each { |name| @conditions.delete(name.to_sym) }
  self
end