【问题标题】:undefined method `and' for #<Arel::Attributes::Attribute#<Arel::Attributes::Attribute 的未定义方法“和”
【发布时间】:2021-09-03 10:36:51
【问题描述】:

我在让查询正常工作时遇到问题。

我实际上是在尝试编写类似于以下 SQL 的内容,将文字 5 替换为变量:

SELECT * 
FROM "my_table"
WHERE 5 BETWEEN "my_table"."minimum" AND "my_table"."maximum"

这是我目前拥有的:

    MyModel.where(
      Arel::Nodes::Between.new(
        my_variable, (MyModel.arel_table[:minimum]).and(MyModel.arel_table[:maximum])
      )
    )

请忽略我使用arel_table的方式,实际查询有多个连接并且更复杂,但这是我必须证明问题的最小可重现示例。

如题主的错误如下:

undefined method `and' for #<Arel::Attributes::Attribute:0x00007f55e15514f8>

【问题讨论】:

    标签: ruby-on-rails-5 arel


    【解决方案1】:

    and 方法适用于Arel::Nodes::Node 即MyModel.arel_attribute[:name].eq(Arel::Nodes::Quoted.new('engineersmnky')) 这是一个Arel::Nodes::Equality,您可以与and 链接。

    话虽如此,您可以通过

    为自己构建一个Arel::Nodes::And
    Arel::Nodes::And.new([left,right])
    

    然后我们可以像这样将它传递给Between 类

    Arel::Nodes::Between.new(
      Arel::Nodes::Quoted.new(my_variable),
      Arel::Nodes::And.new([
        MyModel.arel_table[:minimum], 
        MyModel.arel_table[:maximum]])
    )
    

    在您的情况下不需要Arel::Nodes::Quoted(也:Arel::Nodes.build_quoted(arg)),因为您的my_variable 是一个Integer,它可以被访问并将被视为Arel::Nodes::SqlLiteral,但我发现最好让arel 决定如何处理引用,以防您的 my_variable 最终成为其他不可访问的 Object

    还有其他方法可以创建 Between 和其他方法来创建 And,具体取决于您要处理的对象。

    between 是 Arel::Predication,这些谓词可用于 Arel::Nodes::Attribute 对象,例如

     MyModel.arel_table[:minimum].between([1,6])
    

    提到的and 可用于Arel::Nodes::Node,并且此类的实例提供了一种方便的方法(create_and)来创建And,因此我们可以执行以下操作:

    Arel::Nodes::Node.new.create_and([
         MyModel.arel_table[:minimum],
         MyModel.arel_table[:maximum]])
    

    还有许多其他方法可以通过使用其他 Arel 类来共同破解此功能,但这应该会让您朝着正确的方向前进。

    【讨论】:

    • 惊人的洞察力和解决方案,非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-16
    • 2017-11-12
    • 2014-01-11
    • 1970-01-01
    • 2022-12-23
    • 2012-03-28
    相关资源
    最近更新 更多