【问题标题】:Arel syntax for ( this AND this) OR ( this AND this)( this AND this) OR ( this AND this) 的 Arel 语法
【发布时间】:2012-04-30 19:15:08
【问题描述】:

我将如何在 Arel (this AND this) OR (this AND this) 中执行此操作

上下文是 rails 3.0.7

【问题讨论】:

    标签: ruby-on-rails arel


    【解决方案1】:

    Mike 的回答基本上就是你要找的

    class Model < ActiveRecord::Base
      def self.this_or_that(a1, a2, a3, a4)
        t = Model.arel_table
        q1 = t[:a].eq(a1).and(t[:b].eq(a2))
        q2 = t[:c].eq(a3).and(t[:d].eq(a4))
        where(q1.or(q2))
      end
    end
    

    一些slides我放在Arel上

    【讨论】:

    • 通过使用 t.grouping 选项,我能够让它工作(在 v4.0.1 中)。使用上面的示例,我仍然得到(a 和 b 或 c 和 d)。您在第 12 页上的幻灯片具有似乎按预期工作的分组语法((a 和 b)或(c 和 d))。
    【解决方案2】:

    我会将这些都放在一个 where 块中。例如,这里有一个基于类似复杂“where”子句的“范围”:

    class Foo < ActiveRecord::Base
      def self.my_complex_where(args)
        where("(col1 = ? AND col2 = ?) OR (col3 = ? AND col4 = ?)", 
              args[:val1], args[:val2], args[:val3], args[:val4])
      end
    end
    

    或者,您可以使用以下表示法:

    class Foo < ActiveRecord::Base
      def self.my_complex_where(args)
        where("(col1 = :val1 AND col2 = :val2) OR (col3 = :val3 AND col4 = :val4)", 
              :val1 => args[:val1], 
              :val2 => args[:val2], 
              :val3 => args[:val3],
              :val4 => args[:val4])
      end
    end
    

    【讨论】:

    • 这不是最好的 Arel 解决方案,因为您仍然需要编写 SQL。
    • 这甚至不是一个真正的解决方案
    【解决方案3】:

    你需要下拉到更原始的 AREL

    t = Model.arel_table
    a = (t[:a].eq(nil).and(t[:b].eq(nil)))
    b = (t[:a].not_eq(nil).and(t[:b].not_eq(nil)))
    Model.where(a.and(b))
    

    【讨论】:

    • 这不反映所要求的逻辑
    • 好收获,会支持你的。这就是我同时回答 2 个类似问题的结果。
    【解决方案4】:

    除了已经给出的答案,您可能还想看看 gem 'squeel'

    例子:

    Person.where{(name =~ 'Ernie%') & (salary < 50000) | (name =~ 'Joe%') & (salary > 100000)}
    

    【讨论】:

      【解决方案5】:

      我不知道辅助方法,但你可以always drop down to (almost) pure SQL

      Client.where("orders_count = ? AND locked = ?", params[:orders], false)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-10-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-11
        • 2013-03-29
        • 1970-01-01
        • 2012-08-18
        相关资源
        最近更新 更多