简体   繁体   English

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

[英]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), 一旦我添加另一个.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?

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! 提前致谢!

@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. 这是我能想到的最好的方法,无需以编程方式构建一个where子句字符串,这可能会导致SQL注入风险。

Keep adding as many conditions as you want. 继续添加任意数量的条件。 Notable, use if something.present? 值得注意的是,使用if.present? instead of your unless something.nil? 而不是你的除非something.nil?

Also, the Metric.all might not be ideal, but whatever you need to get all records to start with. 此外,Metric.all可能不是理想的,但无论你需要什么来开始所有记录。

If you want clean code, use scope 如果您想要干净的代码,请使用scope

In metric.rb 在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)`

Write the following method in your Array class 在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

You can build your conditions for ActiveRecord where or find with conditions as follows 您可以为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)

This will be helpful in building multiple conditions with AND/OR combinations 这将有助于使用AND / OR组合构建多个条件

What about something like this? 这样的事情怎么样?

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

Try with the following code 请尝试使用以下代码

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM