How to best do WHERE's conditional with ActiveRecord in Rails?

0

I'm working with JSON in Rails. Imagine the route:

# rota: pessoas.json
def index
  @pessoas = Pessoa.all
end

That's easy! But if I want to add an optional search by age would have to have a condition:

# rota: pessoas.json?idade=30
def index
  if params[:idade]
    @pessoas = Pessoa.where("idade = ?", params[:idade])
  else
    @pessoas = Pessoa.all
  end
end

This is not the end of the world, but it gets harder with more optional parameters:

pessoas.json
pessoas.json?idade=30
pessoas.json?sexo=m
pessoas.json?idade=30&sexo=m

What is the best way (more DRY) to do this search where the parameters are optional?

    
asked by anonymous 06.08.2014 / 15:41

2 answers

2

where accepts a condition hash as a parameter . So in that case you could simply do:

@pessoas = Pessoa.where(params)

If you want to restrict allowed filters, you could use strong_parameters, for example:

@pessoas = Pessoa.where(params.permit(:idade, :sexo))

If you need to use more complex conditions, for example, using comparatives, then you could use chaining:

@pessoas = Pessoa.all
@pessoas = @pessoas.where('idade >= ?', params[:idade_minima]) if params[:idade_minima]
@pessoas = @pessoas.where('sexo = ?', params[:sexo]) if params[:sexo]

If there are many and you want to leave this DRY code you could do:

@pessoas = Pessoa.all
condicoes = {
   idade_minima: 'idade >= ?',
   sexo: 'sexo = ?',
}
condicoes.each do |atributo, condicao|
   @pessoas = @pessoas.where(condicao, params[atributo]) if params[atributo]
end
    
07.08.2014 / 14:22
1

Use the gem ransack .

The most "idiomatic" way to do it without using gems would be:

@pessoas = Pessoa.all
@pessoas = @pessoas.where("idade = ?", params[:idade]) if params[:idade]
    
06.08.2014 / 20:27