Class: Sphinxsearchlogic::Search
- Inherits:
-
Object
- Object
- Sphinxsearchlogic::Search
- Includes:
- Ordering, Pagination
- Defined in:
- lib/sphinxsearchlogic.rb
Defined Under Namespace
Modules: Implementation, Ordering, Pagination Classes: UnknownConditionError
Instance Attribute Summary collapse
-
#all ⇒ Object
Accessors that define this Search object.
-
#conditions ⇒ Object
Accessors that define this Search object.
-
#current_scope ⇒ Object
Accessors that define this Search object.
-
#klass ⇒ Object
Accessors that define this Search object.
-
#params ⇒ Object
Accessors that define this Search object.
-
#scopes ⇒ Object
Accessors that define this Search object.
-
#with ⇒ Object
Accessors that define this Search object.
-
#with_all ⇒ Object
Accessors that define this Search object.
-
#without ⇒ Object
Accessors that define this Search object.
Attributes included from Ordering
#order, #order_attribute, #order_direction
Attributes included from Pagination
#max_matches, #page, #per_page
Instance Method Summary collapse
-
#attribute_filter_options ⇒ Object
Returns a hash for the ThinkingSphinx search method.
-
#cast_type(name) ⇒ Object
Returns the type we should type_cast a ThinkingSphinx::Attribute to, eg.
-
#has_sphinx_index? ⇒ Boolean
Returns true if the class of this Search has a Sphinx index.
-
#initialize(klass, current_scope, params = {}) ⇒ Search
constructor
Creates a new search object for the given class.
-
#is_sphinx_attribute?(attribute_name) ⇒ Boolean
Returns true if the class of this search has a public attribute with this name (or name_sort if field is :sortable).
-
#is_sphinx_field?(field_name) ⇒ Boolean
Returns true if the class of this search has a public field with this name.
-
#is_sphinx_scope?(scope_name) ⇒ Boolean
Returns true if class of this search has a sphinx scope with this name.
-
#method_missing(name, *args, &block) ⇒ Object
Handles (in order): * with / without / with_all conditions (Filters) * field conditions (Regular searches) * scope conditions.
-
#results ⇒ Object
Returns actual search results.
-
#search_options ⇒ Object
Returns a hash for the ThinkingSphinx search method.
-
#sphinx_attribute(attribute_name) ⇒ Object
Returns particular ThinkingSphinx::Attribute.
-
#sphinx_index ⇒ Object
Returns the ThinkingSphinx index for the klass we search on.
-
#type_cast(value, type) ⇒ Object
type_cast method of Searchlogic plugin.
Methods included from Ordering
Methods included from Pagination
#default_per_page, #last_page, #offset, #pagination_options
Constructor Details
#initialize(klass, current_scope, params = {}) ⇒ Search
Creates a new search object for the given class. Ex:
Searchlogic::Search.new(User, {}, {:username_like => "bjohnson"})
133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/sphinxsearchlogic.rb', line 133 def initialize(klass, current_scope, params = {}) @with = {} @without = {} @with_all = {} @conditions = {} @scopes = {} self.klass = klass raise "No Sphinx indexes found on #{klass.to_s}!" unless has_sphinx_index? self.current_scope = current_scope self.params = params if params.is_a?(Hash) end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args, &block) ⇒ Object
Handles (in order):
-
with / without / with_all conditions (Filters)
-
field conditions (Regular searches)
-
scope conditions
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 |
# File 'lib/sphinxsearchlogic.rb', line 181 def method_missing(name, *args, &block) name = name.to_s if name =~ /^(\w+)=$/ # If we have a setter name = $1 if name =~ /^with(out|_all)?_(\w+)$/ attribute_name = $2.to_sym if is_sphinx_attribute?(attribute_name) # Put in with / without / with_all depending on what the regexp matched. if $1 == 'out' without[attribute_name] = type_cast(args.first, cast_type(attribute_name)) elsif $1 == '_all' with_all[attribute_name] = type_cast(args.first, cast_type(attribute_name)) else with[attribute_name] = type_cast(args.first, cast_type(attribute_name)) end else raise UnknownConditionError.new(attribute_name) end elsif is_sphinx_field?(name) conditions[name.to_sym] = args.first elsif is_sphinx_scope?(name) scopes[name.to_sym] = args.first else # If we have an unknown setter.. # raise UnknownConditionError.new(attribute_name) super end else if name =~ /^with(out|_all)?_(\w+)$/ attribute_name = $2 attribute_name = attribute_name.gsub(/_before_type_cast$/, '').to_sym if is_sphinx_attribute?(attribute_name) # Put in with / without / with_all depending on what the regexp matched. if $1 == 'out' without[attribute_name] elsif $1 == '_all' with_all[attribute_name] else with[attribute_name] end else raise UnknownConditionError.new(attribute_name) end elsif is_sphinx_field?(name) conditions[name.to_sym] elsif is_sphinx_scope?(name) scopes[name.to_sym] else # If we have something else than a setter.. # raise UnknownConditionError.new(attribute_name) super end end end |
Instance Attribute Details
#all ⇒ Object
Accessors that define this Search object.
39 40 41 |
# File 'lib/sphinxsearchlogic.rb', line 39 def all @all end |
#conditions ⇒ Object
Accessors that define this Search object.
39 40 41 |
# File 'lib/sphinxsearchlogic.rb', line 39 def conditions @conditions end |
#current_scope ⇒ Object
Accessors that define this Search object.
39 40 41 |
# File 'lib/sphinxsearchlogic.rb', line 39 def current_scope @current_scope end |
#klass ⇒ Object
Accessors that define this Search object.
39 40 41 |
# File 'lib/sphinxsearchlogic.rb', line 39 def klass @klass end |
#params ⇒ Object
Accessors that define this Search object.
39 40 41 |
# File 'lib/sphinxsearchlogic.rb', line 39 def params @params end |
#scopes ⇒ Object
Accessors that define this Search object.
39 40 41 |
# File 'lib/sphinxsearchlogic.rb', line 39 def scopes @scopes end |
#with ⇒ Object
Accessors that define this Search object.
39 40 41 |
# File 'lib/sphinxsearchlogic.rb', line 39 def with @with end |
#with_all ⇒ Object
Accessors that define this Search object.
39 40 41 |
# File 'lib/sphinxsearchlogic.rb', line 39 def with_all @with_all end |
#without ⇒ Object
Accessors that define this Search object.
39 40 41 |
# File 'lib/sphinxsearchlogic.rb', line 39 def without @without end |
Instance Method Details
#attribute_filter_options ⇒ Object
Returns a hash for the ThinkingSphinx search method. Eg.
{
:with => {:year => 2001}
}
240 241 242 243 244 245 246 |
# File 'lib/sphinxsearchlogic.rb', line 240 def = {} [:with] = with unless with.blank? [:without] = without unless without.blank? [:with_all] = with_all unless with_all.blank? # See http://www.mailinglistarchive.com/[email protected]/msg00351.html end |
#cast_type(name) ⇒ Object
Returns the type we should type_cast a ThinkingSphinx::Attribute to, eg. :integer.
304 305 306 |
# File 'lib/sphinxsearchlogic.rb', line 304 def cast_type(name) sphinx_attribute(name).type end |
#has_sphinx_index? ⇒ Boolean
Returns true if the class of this Search has a Sphinx index.
273 274 275 276 277 |
# File 'lib/sphinxsearchlogic.rb', line 273 def has_sphinx_index? sphinx_index.is_a?(ThinkingSphinx::Index) rescue false end |
#is_sphinx_attribute?(attribute_name) ⇒ Boolean
Returns true if the class of this search has a public attribute with this name (or name_sort if field is :sortable).
287 288 289 |
# File 'lib/sphinxsearchlogic.rb', line 287 def is_sphinx_attribute?(attribute_name) !!sphinx_attribute(attribute_name) end |
#is_sphinx_field?(field_name) ⇒ Boolean
Returns true if the class of this search has a public field with this name.
292 293 294 295 296 |
# File 'lib/sphinxsearchlogic.rb', line 292 def is_sphinx_field?(field_name) !sphinx_index.fields.find do |index_field| index_field.public? && (index_field.unique_name.to_s == field_name.to_s) end.nil? end |
#is_sphinx_scope?(scope_name) ⇒ Boolean
Returns true if class of this search has a sphinx scope with this name.
299 300 301 |
# File 'lib/sphinxsearchlogic.rb', line 299 def is_sphinx_scope?(scope_name) klass.sphinx_scopes.include?(scope_name.to_sym) end |
#results ⇒ Object
Returns actual search results.
Movie.sphinxsearchlogic.results
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
# File 'lib/sphinxsearchlogic.rb', line 157 def results Rails.logger.debug("Sphinxsearchlogic: #{klass.to_s}.search('#{all}', #{search_options.inspect})") if scopes.empty? klass.search(all, ) else cloned_scopes = scopes.clone # Clone scopes since we're deleting form the hash. # Get the first scope and call all others on this one.. first_scope = cloned_scopes.keys.first first_args = cloned_scopes.delete(first_scope) result = klass.send(first_scope, first_args) # Call remaining scopes on this scope. cloned_scopes.each do |scope, args| result = result.send(scope, args) end result.search(all, ) end end |
#search_options ⇒ Object
Returns a hash for the ThinkingSphinx search method. Eg.
{
:conditions => {:name => 'John'}
}
252 253 254 255 256 |
# File 'lib/sphinxsearchlogic.rb', line 252 def = {} [:conditions] = conditions unless conditions.blank? .merge().merge().merge() end |
#sphinx_attribute(attribute_name) ⇒ Object
Returns particular ThinkingSphinx::Attribute.
280 281 282 283 284 |
# File 'lib/sphinxsearchlogic.rb', line 280 def sphinx_attribute(attribute_name) sphinx_index.attributes.find do |index_attribute| index_attribute.public? && index_attribute.unique_name.to_s =~ /^#{attribute_name}(_sort)?$/ # Also check for :sortable attributes (they are given prefix _sort) end end |
#sphinx_index ⇒ Object
Returns the ThinkingSphinx index for the klass we search on.
267 268 269 270 |
# File 'lib/sphinxsearchlogic.rb', line 267 def sphinx_index klass.define_indexes if klass.sphinx_indexes.blank? klass.sphinx_indexes.first end |
#type_cast(value, type) ⇒ Object
type_cast method of Searchlogic plugin
309 310 311 312 313 314 315 316 317 318 319 320 321 |
# File 'lib/sphinxsearchlogic.rb', line 309 def type_cast(value, type) case value when Array value.collect { |v| type_cast(v, type) } else # Let's leverage ActiveRecord's type casting, so that casting is consistent # with the other models. column_for_type_cast = ::ActiveRecord::ConnectionAdapters::Column.new("", nil) column_for_type_cast.instance_variable_set(:@type, type) value = column_for_type_cast.type_cast(value) Time.zone && value.is_a?(Time) ? value.in_time_zone : value end end |