Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple query conditions in Rails - if they exist.

I found a few similar questions while searching here, but when I tried to add unless to the solutions I found, things started to break...

Here's what I have that works:

Controller:

    @metrics = Metric.where("current_ratio > ?", @screen.current_ratio_min) unless @screen.current_ratio_min.nil?

Once I add another .where line (of which I need to add many),

    @metrics = Metric.where("current_ratio > ?", @screen.current_ratio_min) unless @screen.current_ratio_min.nil?
    .where("current_ratio < ?", @screen.current_ratio_max) unless @screen.current_ratio_max.nil?

I get an error:

undefined method `where' for false:FalseClass

I'm assuming this is because the first unless is ending my query. How do I apply an unless just to each individual condition? If that is, in fact, the problem :\

Thanks in advance!

like image 323
jon Avatar asked Jul 08 '13 04:07

jon


2 Answers

@metrics = Metric.all
@metrics = @metrics.where('current_ratio > ?', @screen.current_ration_min) if @screen.current_ratio_min.present?
@metrics = @metrics.where('other_value > ?', @screen.other_value) if @screen.other_value.present?

This is the best way I can think of without programmatically building a where clause string which can be risky for SQL injection.

Keep adding as many conditions as you want. Notable, use if something.present? instead of your unless something.nil?

Also, the Metric.all might not be ideal, but whatever you need to get all records to start with.

like image 149
Joel Friedlaender Avatar answered Oct 20 '22 20:10

Joel Friedlaender


If you want clean code, use scope

In metric.rb

  scope :current_ratio_min, lambda {|current_ratio_min|
    current_ratio_min.present? ? where('current_ratio > ?', current_ration_min) : where()}
  scope :current_ratio_max, lambda {|current_ratio_max|
    current_ratio_max.present? ? where('current_ratio > ?', current_ratio_max) : where()}

Your query :

@metrics = Metric.current_ratio_min(@screen.current_ratio_min).current_ratio_max(@screen.current_ratio_max)`
like image 1
user2503775 Avatar answered Oct 20 '22 20:10

user2503775