Страницы

Поиск по вопросам

понедельник, 8 июля 2019 г.

Почему не работает find_by после связи has_many?

В экшене show нахожу пост:
@post = policy_scope(Post).find(params[:id])
Там же нахожу одну главную категорию:
@category = @post.categories.actual
actual выглядит следующим образом:
scope :actual, (-> { find_by(actual: true) })
Этот код работает правильно лишь в одном случае - когда существует категория с флагом actual
Если все категории поста носят в себе actual равный false, то find_by(actual: true) ни на что не повлияет и пользователь получит список всех категорий этого поста.
Также я заменил actual на find_by(actual: true) и все заработало. То есть проблема конкретно в реализации через scope
И раз проблема была в scope, то я заменил его на это:
def self.actual find_by(actual: true) end
И этот вариант работает.
Далее заменяю на этот вариант:
scope :actual, (-> { where(actual: true) })
Возвращается мне [], то есть все верно. Но как только после where прописываю take или first, то получаю снова все категории.
Почему это происходит?
P.S. В данный момент policy_scope примитивный и имеет в себе либо scope.all, либо scope.all.where(published: true). В данном примере scope.all


Ответ

Метод where возвращает объект ActiveRecord_Relation, к которому вы можете применять методы ActiveRecord, метод Enumerable#take возвращет массив, а ActiveRecord::FinderMethods#find_by — объект модели. Возвращать из scope, что-то отличное от ActiveRecord_Relation неправильно, так как вы не можете дальше пользоваться полученным объектом в цепочке вызовов, как это происходит с другими методами ActiveRecord. Считается, что создавая такие scope-ы, вы запутываете коллег по проекту.

Комментариев нет:

Отправить комментарий