2014-07-18 64 views
2

當我撥打以下:的ActiveRecord加入 「DESC」 隨機到ORDER BY

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 

它將「DESC」隨機添加到ORDER BY聲明中。這是一個AR問題還是我做錯了什麼?

注意:這隻發生在我撥打last時。我正在使用ActiveRecord 4.1.1

+3

它不會隨機添加DESC。它每次你添加.last,它是正確的? – infused

+0

我會稱之爲「隨機」,因爲它不像預期的那樣。 –

+0

我會稱之爲「意外」。 –

回答

0

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字符串拆分,並在各個位置將這些碎片粘貼回DESC。這當然不起作用,如果你的ORDER BY使用諸如函數調用之類的「高級」東西。

您可以將該函數調用添加到您的SELECT幷包含一個別名,然後.order('your_column_alias')來隱藏來自AR的逗號。

你也可以假裝last不存在,並使用first代替:

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

當然,這是假設你知道ORDER BY的結構。