Rails:rails 模型的默认排序顺序? [英] Rails: Default sort order for a rails model?
问题描述
我想在我的模型中指定一个默认的排序顺序.
I would like to specify a default sort order in my model.
这样,当我在不指定 .order()
的情况下执行 .where()
时,它使用默认排序.但是如果我指定一个 .order()
,它会覆盖默认值.
So that when I do a .where()
without specifying an .order()
it uses the default sort. But if I specify an .order()
, it overrides the default.
推荐答案
default_scope
这适用于 Rails 4+:
default_scope
This works for Rails 4+:
class Book < ActiveRecord::Base
default_scope { order(created_at: :desc) }
end
对于 Rails 2.3、3,你需要这个:
For Rails 2.3, 3, you need this instead:
default_scope order('created_at DESC')
对于 Rails 2.x:
For Rails 2.x:
default_scope :order => 'created_at DESC'
其中 created_at
是您希望对其进行默认排序的字段.
Where created_at
is the field you want the default sorting to be done on.
注意:ASC 是用于升序的代码,DESC 用于降序(desc
, NOT dsc
!).
一旦你习惯了,你也可以使用scope
:
Once you're used to that you can also use scope
:
class Book < ActiveRecord::Base
scope :confirmed, :conditions => { :confirmed => true }
scope :published, :conditions => { :published => true }
end
对于 Rails 2,您需要 named_scope
.
For Rails 2 you need named_scope
.
:published
范围为您提供 Book.published
而不是Book.find(:published => true)
.
:published
scope gives you Book.published
instead of
Book.find(:published => true)
.
从 Rails 3 开始,您可以通过在它们之间用句点连接它们来链接"这些方法,因此对于上述范围,您现在可以使用 Book.published.confirmed
.
Since Rails 3 you can 'chain' those methods together by concatenating them with periods between them, so with the above scopes you can now use Book.published.confirmed
.
使用此方法,直到需要实际结果(延迟评估)才会实际执行查询,因此可以将 7 个范围链接在一起,但只会产生 1 个实际数据库查询,以避免执行 7 个单独查询时出现性能问题.
With this method, the query is not actually executed until actual results are needed (lazy evaluation), so 7 scopes could be chained together but only resulting in 1 actual database query, to avoid performance problems from executing 7 separate queries.
您可以使用传入的参数,例如 date 或 user_id(会在运行时更改的参数,因此需要使用 lambda 进行惰性求值",如下所示:
You can use a passed in parameter such as a date or a user_id (something that will change at run-time and so will need that 'lazy evaluation', with a lambda, like this:
scope :recent_books, lambda
{ |since_when| where("created_at >= ?", since_when) }
# Note the `where` is making use of AREL syntax added in Rails 3.
最后,您可以通过以下方式禁用默认范围:
Finally you can disable default scope with:
Book.with_exclusive_scope { find(:all) }
甚至更好:
Book.unscoped.all
这将禁用任何过滤器(条件)或排序(排序依据).
which will disable any filter (conditions) or sort (order by).
请注意,第一个版本适用于 Rails2+,而第二个(无作用域)仅适用于 Rails3+
所以......如果你在想,嗯,那么这些就像方法一样......,是的,这正是这些范围!
它们就像拥有 def self.method_name ...code... end
但与 ruby 一样,它们是很好的小语法快捷方式(或糖"),让您更轻松!
So
... if you're thinking, hmm, so these are just like methods then..., yup, that's exactly what these scopes are!
They are like having def self.method_name ...code... end
but as always with ruby they are nice little syntactical shortcuts (or 'sugar') to make things easier for you!
实际上,它们是类级别的方法,因为它们对 1 组所有"记录进行操作.
In fact they are Class level methods as they operate on the 1 set of 'all' records.
然而,它们的格式正在发生变化,在 Rails 4 中,在使用 #scope 而不传递可调用对象时会出现弃用警告. 例如范围 :red, where(color: 'red') 应该更改到 scope :red, ->{ where(color: 'red') }
.
Their format is changing however, with rails 4 there are deprecation warning when using #scope without passing a callable object. For example scope :red, where(color: 'red') should be changed to scope :red, -> { where(color: 'red') }
.
附带说明,如果使用不当,默认_scope 可能会被误用/滥用.
这主要是关于它何时被用于where
限制(过滤)默认 选择(默认的坏主意)等操作而不仅仅是用于排序结果.
对于 where
选择,只需使用常规命名范围.并在查询中添加该范围,例如Book.all.published
其中 published
是命名范围.
As a side note, when used incorrectly, default_scope can be misused/abused.
This is mainly about when it gets used for actions like where
's limiting (filtering) the default selection (a bad idea for a default) rather than just being used for ordering results.
For where
selections, just use the regular named scopes. and add that scope on in the query, e.g. Book.all.published
where published
is a named scope.
总而言之,范围真的很棒,可以帮助您将事情推到胖模型瘦控制器"DRYer 方法的模型中.
In conclusion, scopes are really great and help you to push things up into the model for a 'fat model thin controller' DRYer approach.
这篇关于Rails:rails 模型的默认排序顺序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!