15

したがって、基本的にBookAuthorの 2 つのクラスがあります。本は複数の著者を持つことができ、著者は複数の本を持つことができます。ブックには、次の既定のスコープがあります。

default_scope :order => "publish_at DESC"

著者のショーページで、その著者に関連するすべての本をリストしたいので、次のように言います...

@author = Author.find(params[:id])
@books = @author.books

これまでのところ、すべて順調です。author#show ページには、その著者に属するすべての書籍が発行日順に一覧表示されます。

本の人気度でソートできるgemも開発中です。

@books = @author.books.sort_by_popularity

問題は、並べ替えを試みるたびに、default_scope が常に邪魔になることです。そして、その前にスコープを解除しようとすると、著者の関係が取り除かれ、データベース内のすべての本が返されます。例えば

@books = @author.books.unscoped.sort_by_popularity # returns all books in database

ActiveRelation except() メソッド を使用してこのようなことを行うことができるかどうか疑問に思っています (これは機能するはずですが、機能しません。順序を無視しますが、default_scope 順序の場合は除きます)

def sort_by_popularity
  self.except(:order).do_some_joining_magic.order('popularity ASC')
  #    |------------|                       |---------------------|
end

なぜこれが機能しないのかについてのアイデアはありますか? これを別の方法で機能させる方法についてのアイデアはありますか? default_scope を取り除くことができることはわかっていますが、これを行う別の方法があるかどうか疑問に思っています。

4

2 に答える 2

31

reorder既存の ORDER BY を完全に置き換えるために使用できるはずです。

reorder(*args)
リレーションで定義された既存の順序を、指定された順序に置き換えます。

だから、このようなもの:

def self.sort_by_popularity
  scoped.do_some_joining_magic.reorder('popularity ASC')
end

そして、そのためにクラスメソッドを使用したいと思いますが、scoped代わりにself、コンテキスト全体がわからないので、間違っているかもしれません。

なぜうまくいかないのかわからないexcept。はdefault_scope、最初ではなく最後 (一種) に適用されるようですが、あまり詳しく調べていません。

于 2012-03-16T23:58:52.727 に答える
1

default_scope紛失や他の注文なしでそれを行うことができます

@books.order_values.prepend 'popularity ASC'
于 2018-07-22T08:34:47.390 に答える