binarylogic / searchlogic

Searchlogic provides object based searching, common named scopes, and other useful tools.
http://rdoc.info/projects/binarylogic/searchlogic
MIT License
1.39k stars 133 forks source link

Array and Range scope values #4

Closed laserlemon closed 15 years ago

laserlemon commented 15 years ago

I love searchlogic, but it leaves out conditions with Array or Range values. For instance, a named scope may look like:

class State < ActiveRecord::Base
  named_scope :by_abbreviation, lambda{|a| {:conditions => {:abbreviation => a}} }
end

One could pass a number of different types of arguments to such a scope:

State.by_abbreviation('MI')
State.by_abbreviation(['MI', 'WA'])
State.by_abbreviation('MA'..'MZ')

These produce the following queries, respectively:

SELECT * FROM `states` WHERE (`states`.`abbreviation` = 'MI')
SELECT * FROM `states` WHERE (`states`.`abbreviation` IN ('MI','WA'))
SELECT * FROM `states` WHERE (`states`.`abbreviation` BETWEEN 'MA' AND 'MZ')

Could these sorts of scopes be built into searchlogic, using "in" and "between" shorthand in the scope names?

ghost commented 15 years ago

Thats a good idea, I will see what I can do to get this in there.

ricsrock commented 15 years ago

+1 -- I've been scratching my head on this one for a while. The scope works in my console when I run it directly, but in the app - which involves searchlogic - the scope doesn't work.

named_scope :occurred_at_between, lambda {|*args| {:conditions => ["alerts.occurred_at >= ? AND alerts.occurred_at <= ?", (args.first), (args.last)]}}

This works in the console, but when added to a search object, it only gets one parameter.

ghost commented 15 years ago

The problem is that the values sent from the form can only be strings, arrays, or hashes. You can't send ranges, etc. In the console this is dioble, but to have range support directly from the params hash is not possible. The only solution is to send an array to the scope and use the first and last values. You could also create an alias scope that handled a single value and translated to whatever scope you wanted to use.

laserlemon commented 15 years ago

That's generally true, but it is entirely possible that a custom param parser is being used.

For instance, I use http://github.com/laserlemon/search_party which gives me search_params containing arrays, ranges, money objects, floats, etc.

Also, searchlogic is obviously much more useful than just passing params to named_scopes. The collection of scopes it adds to the picture are half the fun. In my case, I needed to pass a possible range value to a scope that queried a model's association. I really would rather not reinvent the wheel as far as the association support that's already been built in.

laserlemon commented 15 years ago

I forked and addressed the issue using AR's existing attribute_condition and expand_range_bind_variables methods, so the behavior is consistent.

ghost commented 15 years ago

I agree, thanks a lot for your commits I applied them.