6

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

这是我的工作:

控制器:

    @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

我假设这是因为第一个除非正在结束我的查询。如何将除非仅应用于每个单独的条件?如果那是,事实上,问题:\

提前致谢!

4

5 回答 5

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

这是我能想到的最好方法,而无需以编程方式构建可能对 SQL 注入有风险的 where 子句字符串。

继续添加尽可能多的条件。值得注意的是,使用 if something.present? 而不是你的除非某事.nil?

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

于 2013-07-08T05:27:01.800 回答
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)`
于 2013-07-08T08:44:13.673 回答
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 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)

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

于 2015-04-07T18:25:40.107 回答
-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
于 2013-07-08T05:54:35.547 回答
-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
于 2013-07-08T04:23:33.480 回答