我正在使用Ruby on Rails 3.2,我想知道是否有办法做到以下几点:
@categories.order('user_id = ? DESC', params[:id])
@categories.order('user_id = ? DESC', @user.id)
# Note: It is almost the same as `@categories.where('user_id = ?', params[:id])`
# but for the `order` clause.
上述语句生成此错误:
ActiveRecord::StatementInvalid (Mysql2::Error: 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, ...
如果您尝试根据 user_id
更改顺序,返回首先匹配的顺序,则应使用 CASE
语句。
在原始SQL中,它看起来像这样:
SELECT * FROM Categories ORDER BY CASE user_id WHEN 34 THEN 1 ELSE 2 END
这会将 user_id 为 34 的所有行置于顶部,其余行保留默认排序。
现在,就像其他人提到的,order
没有任何机制来清理 SQL,因此您必须在 ActiveRecord::Base
上使用受保护的类方法。
它可能看起来像这样:
order_sql = Category.send :sanitize_sql_array, ["CASE user_id WHEN ? THEN 1 ELSE 2 END", some_user_id]
@categories.order(order_sql)
你不能做ORDER BY user_id = <some_integer>
.您只能按 ASC 或 DESC 列排序。有一些使用 CASE 关键字的高级案例。请阅读 mysql 文档。
http://apidock.com/rails/ActiveRecord/QueryMethods/order
如果您查看源代码,与 where 子句源代码相比,它看起来对问号没有任何作用。 http://apidock.com/rails/ActiveRecord/QueryMethods/where
看看 GitHub 也看排序方法,与问号无关:https://github.com/rails/rails/blob/master/activerecord/lib/active_record/relation/query_methods.rb#L234
您可以像这样封装 where 和 order 方法:
Model.where("user_id = ?", params[:id]).order("field_name DESC")
我认为这应该为你做。我希望我正确地理解了它。