轨道模型的默认sorting顺序?

我想在我的模型中指定一个默认的sorting顺序。

所以,当我做一个.where()没有指定.order()它使用默认sorting。 但是,如果我指定.order() ,它将覆盖默认值。

default_scope

这适用于Rails 4+:

 class Book < ActiveRecord::Base default_scope { order(created_at: :desc) } end 

对于Rails 2.3,3,你需要这个:

 default_scope order('created_at DESC') 

对于Rails 2.x:

 default_scope :order => 'created_at DESC' 

其中created_at是你想要默认sorting的字段。

注: ASC是用于升序的代码, DESC用于降序( descNOT dsc !)。

scope

一旦你习惯了,你也可以使用scope

 class Book < ActiveRecord::Base scope :confirmed, :conditions => { :confirmed => true } scope :published, :conditions => { :published => true } end 

对于Rails 2,你需要named_scope

:published范围给你Book.published而不是Book.find(:published => true)

由于Rails 3可以通过将这些方法与它们之间的句点连接在一起来“链接”这些方法,所以现在可以使用Book.published.confirmed

使用这种方法,只有在需要实际结果(懒惰评估)时,才能实际执行查询,因此可以将7个作用域链接在一起,但仅导致1个实际的数据库查询,以避免执行7个单独查询时的性能问题。

你可以使用一个传入的参数,例如date或者user_id(在运行时会改变的东西,所以需要用'lazy evaluation',用一个lambda,像这样:

 scope :recent_books, lambda { |since_when| where("created_at >= ?", since_when) } # Note the `where` is making use of AREL syntax added in Rails 3. 

最后,您可以使用以下命令来禁用默

 Book.with_exclusive_scope { find(:all) } 

甚至更好:

 Book.unscoped.all 

这将禁用任何filter(条件)或sorting(按顺序)。

请注意,第一个版本在Rails2 +中工作,而第二个版本(unscoped)仅在Rails3 +中使用


所以 ……如果你在想,呃,那么这些就像方法那么…呃,这正是这些范围!
他们就像def self.method_name ...code... end但一如既往的ruby,他们是很好的语法快捷方式(或“糖”),使您更容易!

事实上,他们是在一套“所有”logging上操作的类级方法。

然而,它们的格式正在改变, 使用rails 4时,如果不使用可调用对象,使用#scope时会出现弃用警告。 例如,作用域:红色,其中(颜色:“红色”)应该改为scope :red, -> { where(color: 'red') }

作为一个侧面说明,如果使用不当, 默认 _scope可能会被滥用/滥用。
这主要是关于什么时候它被用于像限制(过滤) 默认select那样的操作(对于缺省而言是一个坏主意 ),而不是用于sorting结果。
对于whereselect,只需使用常规的命名范围即可。 并在查询中添加该范围,例如Book.all.published ,其中published是命名范围。

总而言之,示波器非常棒,可以帮助您将事物推入“胖模式瘦控制器”DRYer方法的模型中。

迈克尔上面的优秀答案的快速更新。

对于Rails 4.0+,你需要把你的sorting放在这样一个块中:

 class Book < ActiveRecord::Base default_scope { order('created_at DESC') } end 

请注意,顺序语句被放置在由大括号表示的块中。

他们改变了它,因为它太容易传递一些dynamic的东西(比如当前时间)。 这消除了问题,因为块在运行时被评估。 如果你不使用块,你会得到这个错误:

支持调用没有块的#default_scope被删除。 例如,而不是default_scope where(color: 'red') ,请使用default_scope { where(color: 'red') } 。 (或者,您可以重新定义self.default_scope。)

正如@丹在下面的评论中提到的,你可以做一个更像ruby的语法:

 class Book < ActiveRecord::Base default_scope { order(created_at: :desc) } end 

或与多个列:

 class Book < ActiveRecord::Base default_scope { order({begin_date: :desc}, :name) } end 

谢谢@丹 !

你可以使用default_scope来实现默认sorting顺序http://api.rubyonrails.org/classes/ActiveRecord/Scoping/Default/ClassMethods.html