Как получить связь на основе области таблицы соединений в Rails - PullRequest
0 голосов
/ 01 апреля 2020

У меня есть три модели: Пользователь, Регистрант, Программа.

Регистрант - это таблица соединения между Пользователем и Программой, которая содержит user_id, program_id и status, что является перечислением.

class User < ApplicationRecord
    has_many :registrants, dependent: :destroy
    has_many :programs, through: :registrants
end
class Registrant < ApplicationRecord
    belongs_to :user
    belongs_to :program

    enum status: {
        enrolled: 1,
        unenrolled: 2,
        instructor: 3,
        passed: 4,
        failed: 5
    }

    scope :active, -> { where(status: [:enrolled, :instructor]) }
end
class Program < ApplicationRecord
    has_many :registrants, dependent: :destroy
    has_many :users, through: :registrants
end

Я хотел бы иметь возможность извлекать только те записи из объединяемой таблицы, которые имеют статус enum: enrolled или: instructor, так что я могу сделать что-то вроде:

program.registrants.active.users

Как мне выполнить sh это?

1 Ответ

0 голосов
/ 02 апреля 2020

Длинных цепочек, таких как program.registrants.active.users, следует избегать из-за Закона Деметры , так что это не является хорошей целью.

Вы можете добавить условия к объединенной таблице в .where, передав a ha sh:

program.users.where(
  registrants: { status: [:enrolled, :instructor] }
)

Обратите внимание, что ключом должно быть имя таблицы (или ее псевдоним в запросе), а не имя ассоциации.

Вы также можете передать область действия:

program.users.where(Registrant.active)

И вы можете убрать это дополнительно, создав ассоциацию "scoped":

class Program < ApplicationRecord
    has_many :registrants, dependent: :destroy
    has_many :users, through: :registrants
    has_many :active_users, 
             through: :registrants,
             source: :user,
             -> { where(Registrant.active) }

end

, которая позволит вам Звоните:

program.active_users # Demeter is happy.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...