Ruby on rails Rails中的多个查询条件(如果存在)。

Ruby on rails Rails中的多个查询条件(如果存在)。,ruby-on-rails,activerecord,conditional-statements,multiple-conditions,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行(其中我需要添加多个)

我假设这是因为第一个函数结束了我的查询。如何仅对每个单独的条件应用一个异常?如果这实际上是问题所在:\


提前谢谢

像这样的东西怎么样

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\u ratio\u min)。其中(“当前比率<?”,@screen.current\u ratio\u max)
elsif@screen.current\u ratio\u min.nil?&@屏幕电流比最大值为零?
@度量=度量。其中(“当前比率<?”,@screen.current\u ratio\u max)
埃尔西夫@屏幕电流比率最小为零@屏幕电流比最大值为零?
@公制=公制。其中(“当前比率>?”,@screen.current\u ratio\u min)
其他的
@metrics=Metric.all
结束
这是我所能想到的最好的方法,不必以编程方式构建where子句字符串,因为SQL注入可能会有风险

继续添加任意多的条件。值得注意的是,如果有什么东西出现,就使用它?而不是你的,除非什么。零


此外,Metric.all可能并不理想,但您需要从获取所有记录开始

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
如果@screen.current\u ratio\u min和@screen.current\u ratio\u max
@度量=度量。其中(“当前比率>和当前比率<?”,@screen.current\u ratio\u min,@screen.current\u ratio\u max)
其他的
除非@screen.current\u ratio\u min.blank?
@公制=公制。其中(“当前比率>?”,@screen.current\u ratio\u min)
其他的
除非@screen.current\u ratio\u max.blank?
@度量=度量。其中(“当前比率<?”,@screen.current\u ratio\u max)
其他的
@metrics=Metric.all
结束
结束
结束

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

公制.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)`

在数组类中编写以下方法

 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 where或find构建条件,条件如下

 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)
条件=[]
条件。添加条件!([“当前比率>?”,@screen.current\u ratio\u min]),除非@screen.current\u ratio\u min.nil?
条件。添加条件!([“当前比率<?”,@screen.current\u ratio\u max]),除非@screen.current\u ratio\u max.nil?
@度量=度量。其中(条件)

这将有助于构建具有和/或组合的多个条件

我没有像应该的那样清楚。有人可以输入最小值,但将最大值留空。在这种情况下,我只想搜索大于最小值的值。如果这有意义的话。如果他有一些可选的过滤器,这将变得非常混乱。在相关部分,我发现了解决我问题的方法,我想。。。我猜如果你不知道该搜索什么,那就很难找到你想要的!想象一下,当您再添加一个可选参数时,这段代码是什么样子。Joel,它根据条件获取有限的记录。如果我们将首先获取所有记录,然后我们将对其应用条件,这意味着对于每个条件,我们需要首先获取所有记录,这可以通过以下方式进行优化:)。确实,我的选项没有查询优化,但此代码将无法使用更多参数。如果他们需要优化,我认为他们需要以编程方式构建查询。我不会以牺牲代码可维护性为代价过早地进行优化。这只在rails 4中有效,在rails 3中,所有人都会执行查询并返回一个数组(您可以在rails 3中使用
scoped
),谢谢!这比我想做的要干净得多。而且看起来更易于启动!感谢大家,显然这是一个比我想象的更复杂的问题!很多好主意:)在Rails4中,将执行多少SQL select?三次?或者仅仅一次?得到了我的问题的答案,rails将惰性地进行计算,所以它将只是一个数据库查询。
@metrics = Metric.current_ratio_min(@screen.current_ratio_min).current_ratio_max(@screen.current_ratio_max)`
 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
 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)