Rails中的多个查询条件 - 如果存在的话。

时间:2013-07-08 04:14:16

标签: ruby-on-rails activerecord conditional-statements multiple-conditions

我在这里搜索时发现了一些类似的问题,但是当我尝试添加时,除非找到我发现的解决方案,否则事情就开始破坏......

这就是我的工作:

控制器:

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

一旦我添加另一个.where行(我需要添加许多行),

    @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?

我收到错误:

undefined method `where' for false:FalseClass

我假设这是因为第一个除非结束我的查询。除非仅针对每个条件,我如何申请?事实上,如果是这个问题:\

提前致谢!

5 个答案:

答案 0 :(得分:7)

@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?

这是我能想到的最好的方法,如果没有以编程方式构建一个where子句字符串,这可能会导致SQL注入风险。

继续添加任意数量的条件。值得注意的是,使用if.present?而不是你的除非something.nil?

此外,Metric.all可能并不理想,但无论你需要什么来开始所有记录。

答案 1 :(得分:1)

如果您想要干净的代码,请使用scope

在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()}

您的查询:

@metrics = Metric.current_ratio_min(@screen.current_ratio_min).current_ratio_max(@screen.current_ratio_max)`

答案 2 :(得分:0)

在Array类中编写以下方法

 class Array
  def add_condition!(condition, conjunction = 'AND')
   if String === condition
     add_condition!([condition])
   elsif Hash === condition
     add_condition!([condition.keys.map { |attr| "#{attr}=?" }.join(' AND ')] + condition.values)
   elsif Array === condition
     unless condition.empty?
       self[0] = "(#{self[0]}) #{conjunction} (#{condition.shift})" unless empty?
       self.push(*condition)
     end
   else
    raise "don't know how to handle this condition type"
   end
  self
 end
end

您可以为ActiveRecord建立条件,在条件中找到或找到条件如下

 conditions = []
 conditions.add_condition!(["current_ratio > ?", @screen.current_ratio_min]) unless @screen.current_ratio_min.nil?  
 conditions.add_condition!(["current_ratio < ?", @screen.current_ratio_max]) unless @screen.current_ratio_max.nil?
 @metrics = Metric.where(conditions)

这将有助于使用AND / OR组合构建多个条件

答案 3 :(得分:-1)

这样的事情怎么样?

if !@screen.current_ratio_min.nil? && !@screen.current_ratio_max.nil?
  @metrics = Metric.where("current_ratio > ?", @screen.current_ratio_min).where("current_ratio < ?", @screen.current_ratio_max)
elsif @screen.current_ratio_min.nil? && !@screen.current_ratio_max.nil?
  @metrics = Metric.where("current_ratio < ?", @screen.current_ratio_max)
elsif !@screen.current_ratio_min.nil? && @screen.current_ratio_max.nil?
  @metrics = Metric.where("current_ratio > ?", @screen.current_ratio_min)
else
  @metrics = Metric.all
end

答案 4 :(得分:-1)

尝试使用以下代码

if @screen.current_ratio_min and @screen.current_ratio_max
  @metrics = Metric.where("current_ratio > ? and current_ratio < ?", @screen.current_ratio_min, @screen.current_ratio_max)
else
 unless @screen.current_ratio_min.blank?
   @metrics = Metric.where("current_ratio > ?", @screen.current_ratio_min)
 else
   unless @screen.current_ratio_max.blank?
     @metrics = Metric.where("current_ratio < ?", @screen.current_ratio_max)
   else
     @metrics = Metric.all
   end
 end 
end