代码之家  ›  专栏  ›  技术社区  ›  nimmolo

AR/Arel-如何组合查询以选择条件列集合

  •  0
  • nimmolo  · 技术社区  · 4 年前

    我有一个模型方法,可以有条件地连接用户的用户名(“login”)和真实姓名,如果他们保存了真实姓名,否则它只显示用户名。我想用ActiveRecord或Arel重写查询。

    看来我应该使用 Arel::Nodes::NamedFunction .但我不知道该怎么做 有条件的 与命名函数连接。(阿雷尔知道“如果”吗?我在文件中找不到任何参考。)

      def primer_values
        connection.select_values(%(
          SELECT CONCAT(users.login,
                        IF(users.name = "", "", CONCAT(" <", users.name, ">")))
          FROM users
          ORDER BY IF(last_login > CURRENT_TIMESTAMP - INTERVAL 1 MONTH,
                      last_login, NULL) DESC,
                    contribution DESC
          LIMIT 1000
        )).uniq.sort
      end
    

    还有一个类似的条件从句。

    1 回复  |  直到 4 年前
        1
  •  2
  •   engineersmnky    4 年前

    鉴于这种用法,我通常讨厌rails中的原始SQL,但我还是保持原样。虽然我可能会把它改成更地道的东西,比如。

    User
      .order(
        Arel.sql("IF(last_login > CURRENT_TIMESTAMP - INTERVAL 1 MONTH,last_login, NULL)").desc,
        User.arel_table[:contribution].desc)
      .limit(1000)
      .pluck(Arel.sql(
        'CONCAT(users.login,
          IF(users.name = "", "", 
            CONCAT(" <", users.name, ">")))'))
      .uniq.sort
    

    将其转换为Arel而不将其抽象为自己的对象将严重损害可读性。

    这只是为了给你一个想法;第一部分是3 NamedFunction s

    1. 海螺
    2. 如果
    3. 海螺
    Arel::Nodes::NamedFuction.new(
      "CONCAT",
      [User.arel_table[:name],
       Arel::Nodes::NamedFuction.new(
         "IF",
         [User.arel_table[:name].eq(''),
          Arel.sql("''"),
          Arel::Nodes::NamedFuction.new(
             "CONCAT",
             [Arel.sql("' <'"),
              User.arel_table[:name],
              Arel.sql("'>'")]
          )]
      )]
    )
    

    A. 命名函数 是的构造函数 FUNCTION_NAME(ARG1,ARG2,ARG3) 因此,任何使用这种语法的SQL都可以使用 命名函数 NOW() 或者其他语法,比如 LATERAL(query) .