我想在模型中指定默认的排序顺序。
这样,当我.where()
不指定而进行操作时,.order()
它将使用默认排序。但是,如果指定.order()
,它将覆盖默认值。
我想在模型中指定默认的排序顺序。
这样,当我.where()
不指定而进行操作时,.order()
它将使用默认排序。但是,如果指定.order()
,它将覆盖默认值。
Answers:
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
您要在其中进行默认排序的字段在哪里。
注意:ASC是用于升序的代码,而DESC是用于降序的(desc
,NOT 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个独立查询时出现性能问题。
您可以使用传入的参数,例如日期或user_id(某些内容会在运行时更改,因此需要使用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
这将禁用任何过滤器(条件)或排序(排序依据)。
请注意,第一个版本适用于Rails2 +,而第二个版本(不受作用域)仅适用于Rails3 +
所以
……如果您在想,嗯,那么这些就像方法一样……是的,这正是这些作用域!
它们就像def self.method_name ...code... end
拥有红宝石一样,但是像往常一样,它们是不错的语法上捷径(或“糖”),可以使您更轻松地工作!
实际上,它们是对1组“全部”记录进行操作的类级别方法。
它们的格式正在改变,但是在使用#scope而不传递可调用对象的情况下,使用rails 4会出现过时警告。例如scope:red,where(color:'red')应该更改为scope :red, -> { where(color: 'red') }
。
附带说明,如果使用不当,则会滥用/滥用默认 _scope。
这主要是关于何时将其用于诸如where
限制(过滤)默认选择(对于默认值的一个坏主意)之类的操作,而不仅仅是将其用于排序结果。
对于where
选择,只需使用常规的命名范围。并在查询中添加该范围,例如Book.all.published
哪里published
是命名范围。
总而言之,范围确实很棒,可以帮助您通过“胖模型瘦控制器” DRYer方法将内容推入模型。
default_scope { order("#{table_name}.created_at DESC") }
吗?
default_scope { order(created_at: :desc) }
4.2.6
似乎updated_at
不是这样created_at
。
updated_at
默认情况下排序?:-|
快速更新了迈克尔在上面的出色答案。
对于Rails 4.0+,您需要将您的排序放在这样的块中:
class Book < ActiveRecord::Base
default_scope { order('created_at DESC') }
end
注意,order语句放置在由花括号表示的块中。
他们更改了它,因为传递动态内容(例如当前时间)太容易了。由于该块是在运行时评估的,因此可以消除问题。如果不使用块,则会出现此错误:
删除了对不带块调用#default_scope的支持。例如
default_scope where(color: 'red')
,请使用代替default_scope { where(color: 'red') }
。(或者,您可以重新定义self.default_scope。)
就像@Dan在下面的评论中提到的那样,您可以像这样使用更红宝石的语法:
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 { order(created_at: :desc) }
,就像您尝试最小化rails中的sql语法一样。<br/>如果要对多列进行排序并且要使用新语法,则可能需要包装desc像这样的胡须中的列default_scope { order({begin_date: :desc}, :name) }
您可以使用default_scope实施默认的排序顺序 http://api.rubyonrails.org/classes/ActiveRecord/Scoping/Default/ClassMethods.html
default_scope
该网页上,因为它已经从被重构ActiveRecord::Base
为ActiveRecord::Scoping::Default::ClassMethods
(api.rubyonrails.org/classes/ActiveRecord/Scoping/Default/...)