4

你好,我有一个Rails 3.2的问题和订购。Rails 3 ORDER BY FIELD and last

当希望通过现场,电话.lastActiveRecord行为古怪的命令集...

>> User.order("FIELD(id, '1')") 
    User Load (0.4ms) SELECT `users`.* FROM `users` ORDER BY FIELD(id, '1') 
    => [] 
    >> User.order("FIELD(id, '1')").first 
    User Load (0.4ms) SELECT `users`.* FROM `users` ORDER BY FIELD(id, '1') LIMIT 1 
    => nil 
    >> User.order("FIELD(id, '1')").last 
    User Load (0.3ms) SELECT `users`.* FROM `users` ORDER BY FIELD(id DESC, '1') DESC LIMIT 1 
    Mysql2::Error: You have an error in your SQL syntax; 

正如你可以看到最后调用的关系添加DESC两次,但它应该只把它在整个ORDER BY FIELD之后,而不是在括号内。

有没有人有一个想法如何做到这一点?

谢谢!

回答

2

这是因为ActiveRecord order方法不支持FIELD函数。使用顺序方法将解析逗号作为字段分隔符,并在调用last时将DESC附加到每个段。

作为替代可以要么)避免使用FIELD(或避免使用last,只是提供正向和反向范围

scope :forward_order, order("FIELD(id, '1') ASC") 
scope :reverse_order, order("FIELD(id, '1') DESC") 

然后就可以代替User.order(...).last

+0

呀,有时ActiveRecord的不能“反向”你'ORDER'指令,你必须做到这一点。 – tadman

2

使用User.reverse_order.first这是老但今天我遇到了这个问题,并找到了一个解决方法,不需要使用额外的范围。

创建一个SQL函数将呼叫打包到FIELD,这样在调用order时将不会有逗号。这是PostgreSQL的,但翻译很简单:

CREATE FUNCTION field1(value text) RETURNS text AS $$ 
BEGIN 
    RETURN FIELD(value, 1); 
END; 
$$ LANGUAGE plpgsql IMMUTABLE 

现在在调用ActiveRecord的last工作:

User.order('field1(id)').last