1

I'm looking for the best method for filtering the records I return to a view in Rails, based on an arbitrary amount of query parameters, e.g:

http://localhost:3000/foo?some_field=fubar&this_field_left_blank=&a_third_field=bar

What I'm currently doing

I have found and used the has_scope gem, which worked rather nicely, but my work colleagues have expressed trepidation that scopes declare class methods of the same name as the fields on the class, e.g:

scope :some_field, -> f { where some_field: f }

where my class looks something like

class Foo
  ....
  attribute :some_field
  ....

I have also considered building a 'chain' of .where clauses by way of a large switch statement, but that seems ugly.

tl;dr

Is there a pattern for filtering records based on query parameters in Rails, and/or a best practice?

My eventual solution

After reading the answer given by Andrew Wei and spending a little more time with the problem, I decided to use a loop over the parameters with responds_to on the class itself, like so:

params.each do |params,value|
  @mymodels = MyModel.send "by_#{filter}", value, @mymodels if MyModel.respond_to? "by_#{filter}" and not value.blank?
end

where each of the MyModel class methods looks something like:

def self.by_some_field(value, relation)
  relation.where some_field: value
end
infused
  • 24,000
  • 13
  • 68
  • 78
xyzjace
  • 432
  • 1
  • 5
  • 16

1 Answers1

2

This is what I usually do. I'm not saying this is the "Rails way".

where = {}

if params[:one]
    where["one"] = params[:one]
end

if params[:two] # .empty? , .nil?, x > 0... etc
    where["two"] = params[:two].to_i
end

@somethings = Something.where(where)

Obviously you would protect how your variables are assigned. I'm just trying to demonstrate the pattern I use.

Andrew Wei
  • 2,020
  • 1
  • 17
  • 28
  • Thanks for that, but I wanted to try and avoid having to build up a where clause like that. The controller code will become too large for my liking. – xyzjace Oct 30 '13 at 05:57