Подтвердить что ты не робот

Переопределить только область по умолчанию (в частности, порядок), и больше ничего в Rails

Итак, в основном у меня есть два класса: Книга и Автор. Книги могут иметь несколько авторов, и авторы могут иметь несколько книг. Книги имеют следующую область по умолчанию.

default_scope :order => "publish_at DESC"

На странице просмотра автора я хочу перечислить все книги, связанные с этим автором, поэтому я говорю следующее...

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

Пока все хорошо. На странице автора # показаны все книги, принадлежащие этому автору, заказанные по дате публикации.

Я также работаю над драгоценным камнем, который способен сортировать по популярности книги.

@books = @author.books.sort_by_popularity

Проблема в том, что всякий раз, когда он пытается сортировать, default_scope всегда мешает. И если я попытаюсь разоблачить его, прежде чем он избавится от отношения автора и вернет каждую книгу в базу данных. Например

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

Мне интересно, могу ли я использовать метод ActiveRelation except() делать что-то вроде этого (кажется, что он должен работать, но это не так. Он игнорирует порядок, а не когда он является порядком по умолчанию)

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

Любые идеи относительно того, почему это не работает? Любые идеи о том, как заставить это работать по-другому? Я знаю, что могу просто избавиться от default_scope, но мне интересно, есть ли другой способ сделать это.

4b9b3361

Ответ 1

Вы можете использовать reorder, чтобы полностью заменить существующий ORDER BY:

Изменение порядка (* арг)
Заменяет любой существующий порядок, определенный в отношении с указанным порядком.

Так что-то вроде этого:

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

И я думаю, вы хотите использовать метод класса для этого и scoped вместо self, но я не знаю весь контекст, поэтому, возможно, я ошибаюсь.

Я не знаю, почему except не работает. default_scope похоже, применяется в конце (вроде), а не в начале, но я не так много смотрел.