基本上我有两个课程,预订和作者。书籍可以有多个作者,作者可以有多本书。书籍具有以下默认范围。
default_scope :order => "publish_at DESC"
在作者展示页面上,我想列出与该作者相关的所有书籍,所以我说以下内容......
@author = Author.find(params[:id])
@books = @author.books
到目前为止一切都很好。作者#show页面列出了按出版日期排序的属于该作者的所有书籍。
我也在研究一种能够按照书籍的受欢迎程度排序的宝石。
@books = @author.books.sort_by_popularity
问题在于,无论何时尝试排序,default_scope总是会妨碍。如果我试图取消它之前它将摆脱作者关系并返回数据库中的每本书。例如
@books = @author.books.unscoped.sort_by_popularity # returns all books in database
我想知道我是否可以使用ActiveRelation except() method 做这样的事情(似乎它应该工作,但事实并非如此。它忽略了顺序,而不是当它是default_scope命令时)
def sort_by_popularity
self.except(:order).do_some_joining_magic.order('popularity ASC')
# |------------| |---------------------|
end
关于为什么这不起作用的任何想法?关于如何以不同的方式工作的任何想法?我知道我可以摆脱default_scope,但我想知道是否有另一种方法可以做到这一点。
答案 0 :(得分:28)
您应该可以使用reorder
来完全替换现有的ORDER BY:
<强>重排序(*参数)强>
用指定的顺序替换在关系上定义的任何现有订单。
这样的事情:
def self.sort_by_popularity
scoped.do_some_joining_magic.reorder('popularity ASC')
end
而且我认为您想要使用类方法而scoped
代替self
,但我不知道整个背景,所以也许我错了。
我不知道为什么except
无效。 default_scope
似乎在最后(某种程度上)应用而不是从头开始,但我还没有对它进行过多次调查。
答案 1 :(得分:0)
您可以做到这一点而不会丢失default_scope
或其他顺序
@books.order_values.prepend 'popularity ASC'