【问题标题】:ActiveRecord adding "DESC" randomly to ORDER BYActiveRecord 将“DESC”随机添加到 ORDER BY
【发布时间】:2014-07-18 00:14:08
【问题描述】:

当我调用以下命令时:

organization = Organization.first
organization.members.order("SUBSTRING_INDEX(SUBSTRING_INDEX(members.name, ' ', 3), ' ', -1)").last

给我以下错误:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 
'DESC, ' ' DESC, 3) DESC, ' ' DESC, -1) DESC LIMIT 1' at line 1: 
SELECT  `members`.* FROM `members`  WHERE `members`.`organization_id` = 2
ORDER BY SUBSTRING_INDEX(SUBSTRING_INDEX(members.name DESC, ' ' DESC, 3) DESC, ' ' DESC, -1) DESC LIMIT 1

问题出在此声明中:

SUBSTRING_INDEX(SUBSTRING_INDEX(members.name DESC, ' ' DESC, 3) DESC, ' ' DESC, -1) DESC LIMIT 1

它在ORDER BY 语句中随机添加“DESC”。这是 AR 问题还是我做错了什么?

注意:这只发生在我致电last 时。我正在使用 ActiveRecord 4.1.1

【问题讨论】:

  • 它不会随机添加DESC。每次添加 .last 时都会这样做,对吗?
  • 我将其称为“随机”,因为它的行为与预期不符。
  • 我会称之为“出乎意料”。
  • 它的行为不应该如此。当我调用.last 时,它应该使用以下SQL:SUBSTRING_INDEX(SUBSTRING_INDEX(members.name, ' ', 3), ' ', -1) DESC。除非这就是 AR 的设计方式(这是一个糟糕的设计)。

标签: ruby-on-rails ruby activerecord rails-activerecord


【解决方案1】:

ActiveRecord 或 AREL 内部的一些东西是对 SQL ORDER BY 子句中逗号的含义做出假设。假设 ORDER BY 是一个类似于 expr1, expr2, ... 的字符串,各个表达式中没有逗号。

当您添加.last 时,AR 最终会在查询中调用reverse_orderreverse_order 对 ORDER BY 子句的格式做了愚蠢的假设,它(或它所调用的东西)假设 SQL ORDER BY 看起来像 expr1, expr2, ...,各个表达式中没有逗号。当reverse_order 尝试颠倒顺序时,它会盲目地将 ORDER BY 字符串拆分为逗号,并将各个部分与DESCs 一起粘贴到各个位置。如果您的 ORDER BY 使用诸如函数调用之类的“高级”事物,这当然不起作用。

您可以将该函数调用添加到您的 SELECT 并为其添加别名,然后使用 .order('your_column_alias') 对 AR 隐藏逗号。

您也可以假装last 不存在并改用first

organization.members.order("SUBSTRING_INDEX(...) DESC").first

这当然假设您知道 ORDER BY 的结构。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-26
    • 2021-07-14
    • 1970-01-01
    • 2020-03-09
    • 2020-02-19
    • 2011-12-22
    相关资源
    最近更新 更多