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

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

这就是我的工作:

控制器:

@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 

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

提前致谢!

 @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可能不是理想的,但无论你需要什么来开始所有记录。

如果您想要干净的代码,请使用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)` 

在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组合构建多个条件

这样的事情怎么样?

 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 

尝试使用以下代码

 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