Rails 3 ORDER BY FIELD和last

时间:2012-08-23 17:19:52

标签: mysql ruby-on-rails activerecord sql-order-by ruby-on-rails-3.2

您好我的Rails 3.2和订购有问题。

当想要按字段订购某个集合时,在调用.last ActiveRecord时表现得非常奇怪......

   >> 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 个答案:

答案 0 :(得分:2)

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

作为替代方案,您可以避免使用FIELD(),或者避免使用last并只提供正向和反向范围

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

然后,您可以使用User.reverse_order.first代替User.order(...).last

答案 1 :(得分:2)

这已经过时但我今天遇到了这个问题,并找到了一个不需要使用额外范围的解决方法。

创建一个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