Переопределить только область по умолчанию (в частности, порядок) и ничего больше в Rails
Так что в основном у меня есть два класса, Книга и Автор. Книги могут иметь несколько авторов, а авторы могут иметь несколько книг. Книги имеют следующую область по умолчанию.
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 кроме (), чтобы сделать что-то подобное (кажется, что это должно работать, но это не так. Он игнорирует порядок, только не тогда, когда это порядок по умолчанию)
def sort_by_popularity
self.except(:order).do_some_joining_magic.order('popularity ASC')
# |------------| |---------------------|
end
Есть идеи, почему это не работает? Любые идеи о том, как заставить это работать по-другому? Я знаю, что могу просто избавиться от default_scope, но мне интересно, есть ли другой способ сделать это.
2 ответа
Вы должны быть в состоянии использовать reorder
полностью заменить существующий ORDER BY:
изменить порядок (* арг)
Заменяет любой существующий порядок, определенный в отношении, указанным порядком.
Так что-то вроде этого:
def self.sort_by_popularity
scoped.do_some_joining_magic.reorder('popularity ASC')
end
И я думаю, что вы хотите использовать метод класса для этого и scoped
вместо self
но я не знаю всего контекста, так что, возможно, я ошибаюсь.
Я не знаю почему except
не работает default_scope
кажется, что применяется в конце (вроде), а не в начале, но я не особо разбираюсь в этом.
Вы можете сделать это без потери default_scope
или другой заказ
@books.order_values.prepend 'popularity ASC'