In an app I'm working on, I want to have a filter in which you can
specify certain attributes and click "filter" to activate an AJAX
request and return a list of, say, machines that match with those
attributes.
No I'm not sure how to build the controller.
If I would specify all the attributes, I would simply do:
But how would I do this if only some of the attributes are specified
and the others are nil? Would I have to create @machines including all
machines and have Rails do the rest of the work or is there a way to
get find to do what I want?
# Define a list of acceptable params for filtering
FILTERS = [:name, :code]
# Finds records by params
def self.filter_by_params(params)
conditions = params.select { |key,val| FILTERS.include?(key.to_sym) and val }
all(:conditions => conditions)
end
end
class MachinesController < ApplicationController
def index
# Where params is { :filter => { :name => 'Pat', :code => '123' }}
@machines = Machine.filter_by_params(params[:filter])
end
Could you explain why the first part would go entirely into the
Machine model?
Because it’s better to encapsulate model logic in the models (and custom finders are model logic). Controllers should only be responsible for receiving a request, calling the appropriate model methods, then returning a response.
That works, though it’s definitely a good idea to sanitize which params can be used in such a manner. Otherwise, someone could send params like { :destroy_all => true } or something, and then there goes your database.
I've decided to try and go with this solution as this actually does
what I inteded to do. I just had some trouble understanding why in
most examples this piece of code is put into the controller and you
don't.