How to Best Do Conditional WHERE’s with Activerecord on Rails?

Asked

Viewed 443 times

0

I’m working with JSON on 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 I 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 isn’t 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 (DRY) way to do this search in which the parameters are optional?

2 answers

2


The where accepted a condition hash as parameter. So in that case you could just do:

@pessoas = Pessoa.where(params)

If you want to restrict the 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, with the use of 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
  • Great answer. The solution Modelo.where( params.permit(...) ) is really the best in the case of the search for equality =)

1

Use the Gem ransack.

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

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

Browser other questions tagged

You are not signed in. Login or sign up in order to post.