Pregunta

I have a form that when filled has to trigger a particular query, depending on which parameters the form has, so I have a method in my model that I believe should look like this:

def form_query(params)

  query = ''
  if params.has_key?('size')
    query = query.where(size: params['size'])
  end

  if params.has_key?('title')
    query = query.where(title: params['title'])
  end

  # More conditionals depending on params.
end

My question is, what does query have to be at the beginning? I put query = '', but I am wondering what has to be the base case, so I can conditionally add more 'where' clauses.

¿Fue útil?

Solución

Queries aren't strings; they're query objects. So you want something like

query = YourModel.scoped # Rails 3; in Rails 4, use .all
if params.has_key?('size')
  query = query.where(size: params['size'])
end

etc.

Otros consejos

Alternatively, you can update your code as below:

  def self.form_query(params)
    options = {}
    fields = ["body", "title"].freeze  ## Add other options
    if params.present?
      fields.each do |field|
        options[field] = params[field] if params[field]
      end
    end
    if options.present?
      where(options) 
    else
       all  ## or nil if you don't want to show any records in view
    end
  end 

Also, form_query should be a class method in your model. Add more options in the fields array that you would like to query against. It not only makes your code compact but also makes a single database call.

Here is a more condensed version of Kirti Thorat's version:

FIELDS = ["size", "title"].freeze  ## Add other options

def self.form_query(params)
  return all unless params.present?

  options = params.select { |k, _v| FIELDS.include? k.to_s }
  options.present? ? where(options) : all
end 

I have done k.to_s so you can pass params keys as either strings or symbols.

If you want to return nil if no params are passed you can do this:

FIELDS = ["size", "title"].freeze  ## Add other options

def self.form_query(params)
  return unless params.present?

  options = params.select { |k, _v| FIELDS.include? k.to_s }
  where(options) if options.present? 
end 
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top