Не нарушая имеющуюся архитектуру данных, я пытаюсь запросить список связей между несколько разобщенными моделями.
Структура модели выглядит следующим образом:
class Course
has_many :course_groups
end
class CourseGroup
belongs_to :course
has_many :assignments
end
class Assignments
belongs_to :course_group
has_many :assignment_tasks, dependent: :destroy
has_many :user_assignments
def completed_by?(user)
UserAssignment.find_by(user: user, assignment: self)&.completed
end
end
class AssignmentTask
has_many :task_files
belongs_to :assignment
has_one :task_evaluation
end
class UserAssignments
belongs_to :assignment
belongs_to :user
end
class User
has_many :user_assignments
end
Я пытаюсь выяснить, сколько CourseGroups Пользователь имеет . Особенно те пользователи, которые завершили все группы CourseGroup, которые связаны с ними. Я не нахожу ничего конкретного, что позволило бы мне получить эту информацию.
Я думал, что смогу создать несколько соединений для получения соединения, например:
User.joins(user_assignments: { assignment: :course_group })
Получается список пользователей. В моей модели CourseGroup у меня есть следующая модель:
def completed_by?(user)
assigns = assignments.map(&:id)
completed = true
assigns.each do |assign|
rec = UserAssignment.find_by(assignment_id: assign, user_id: user.id)
completed = false if rec.nil? || rec.completed == false
end
completed
end
Я не могу понять, как получить этот метод на модели User
, чтобы запросить его или как лучше перестроить его.
Моей первой мыслью было, возможно, что я мог бы построить свой первоначальный запрос как область действия и что я мог бы получить метод таким способом, но область действия не удалась, что написано:
scope :course_user, -> { joins(user_assignments: { assignment: :course_group }) }
Я имею в виду в идеале я мог бы поместить в область действия метода.
Есть ли способ получить метод в области действия, или я должен просто создать на пользовательской модели метод с запросом, а затем воссоздать метод, который я Придется разобраться.
РЕДАКТИРОВАТЬ : добавлено больше классов и метод, который используется в Назначениях. CourseGroup традиционно не помечается как завершенная. Назначения не появляются в списке пользователя, пока он фактически не завершен. Вместо этого они полностью назначены для CourseGroup. Таким образом, завершенная группа CourseGroup полагается на все задания, которые должны быть помечены как выполненные.
Итак, от CourseGroup есть завершенная_by? метод, на который затем ссылается помощник:
def groups_completed(user)
CourseGroup.ordered.select { |group| group.completed_by?(user) }
end
def groups_incomplete(user)
CourseGroup.ordered.select { |group| group.completed_by?(user) == false }
end
Не очень легко узнать, завершил ли пользователь группу CourseGroup, пока он не выполнил все задания, а затем те были добавлены в его учетную запись.
EDIT : обновлена модель User с некоторыми изменениями для перспективы того, где находится код.
has_many :user_assignments
has_many :assignments, through: :user_assignments, source: :assignment
has_many :course_groups, through: :assignments, source: :course_group
def completed_ipp_courses
completed = true
all_users = User.joins(:course_groups)
all_users.each do |group|
completed = false unless group.course_completion?
end
return self if completed
return nil
end
def course_completion?(user)
collection = User.all.each do |top|
top.course_groups.each do |list|
list.assignments.map(&:id)
end
end
completed = true
collection.each do |assign|
rec = UserAssignment.find_by(assignment_id: assign, user_id: user.id)
completed = false if rec.nil? || rec.completed == false
end
end
Идея состоит в том, что завершенный метод выполняет соединение и проверяет завершено в рамках завершения? метод. Завершение? Метод запускает всех пользователей и выполняет проверку UserAssignments для завершения. Нет ошибок, пока ... re c line. Теперь он возвращает неопределенную локальную переменную или метод для пользователя