On Sep 16, 3:15 pm, Michael Granger <[email protected]> wrote:
> Joe Van Dyk wrote:
> > I often need to do something like:
>
> > def search *keywords
> >    select * from something where column ilike '%first-keyword%' OR
> > column ilike '%second-keyword%' ......;
> > end
>
> > So, the query would contain an arbitrary amount of OR'd conditions,
> > depending on how many keywords were passed in to the search function.
>
> > I'm having trouble getting sequel to do the right syntax.  If I wanted
> > AND instead of ORs, I could do something like:
>
> > query = DB[:table]....
> > keywords.each { |k| query = query.filter("column ilike ?, "%#{k}%" }
>
> The Dataset#or method can add ORs:
>
>      query = keywords.inject( DB[:table] ) do |query,kw|
>          pat = '%' + kw
>          if query.send( :simple_select_all? )
>              query.filter( :column.ilike(pat) )
>          else
>              query.or( :column.ilike(pat) )
>          end
>      end
>
> It's violating the 'protected' visibility of the
> Dataset#simple_select_all? method, but I'm not sure how to know when to
> use #or and when to use #filter otherwise. Suggestions, Jeremy?
>
> If you want to avoid the #send, you could always just unshift the first
> keyword, start your query with that, and inject the rest.

Aha!

query.filter(keywords.map { |k| ["products.name ilike ?", "%#{k}
%"] }.sql_or)

Given keywords ["this", "rocks", "a lot"], this results in:

... AND (('products.name ilike ?' = '%this%') OR ('products.name
ilike ?' = '%rocks%') OR ('products.name ilike ?' = '%a lot%'))

-- 
You received this message because you are subscribed to the Google Groups 
"sequel-talk" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/sequel-talk?hl=en.

Reply via email to