1

У меня есть модели Workout и User, которые связаны с многими из многих через модель UserWorkout. А модель UserWorkout имеет атрибут: is_creator, который показывает, каким пользователем был создатель. Но у тренировки должен быть только один создатель. Каков наилучший способ добавить такую ​​проверку?Rails has_many: через проверку вложенных записей подсчитывается по определенному параметру

class Workout < ActiveRecord::Base 

    has_many :user_workouts, inverse_of: :workout, dependent: :destroy 
    has_many :participants, through: :user_workouts, source: :user 

    def creator 
    participants.where(user_workouts: { is_creator: true }).order('user_workouts.created_at ASC').first 
    end 

end 

class UserWorkout < ActiveRecord::Base 

    belongs_to :user 
    belongs_to :workout 

end 

class User < ActiveRecord::Base 

    has_many :user_workouts, inverse_of: :user, dependent: :destroy 
    has_many :workouts, through: :user_workouts 

end 

ответ

1

Прежде всего есть конструктивный недостаток в вашей структуры БД. Думаю, is_creator не должно быть в UserWorkout. Это ответственность Workout

Другими словами Workout могут быть созданы пользователем и User может создать много Workout, так что это один-многим между User и Workout

Держите created_by_id в Workout и добавить ассоциации в нем. Это упростит и упростит многое.

class Workout < ActiveRecord::Base 

    has_many :user_workouts, inverse_of: :workout, dependent: :destroy 
    has_many :participants, through: :user_workouts, source: :user 

    belongs_to :creator , class_name: "User", foreign_key: "created_by_id" 

end 

и есть привычка быть никакой необходимости проверять уникальность, поскольку это единственный столбец тренировки

Теперь вам не нужен сложный запрос, как каждый раз, когда вам нужно найти создатель тренировки. Это простая ассоциация belongs_to. Все будет заботиться по рельсам :)

+0

спасибо за хорошую идею) –

2

В зависимости от СУБД, вы можете добавить filtered/partial index на workout_id where is_creator = true

На активном уровне записи, вы можете добавить custom validation

class UserWorkout 
    validate :workout_has_only_one_creator 

    private 

    def workout_has_only_one_creator 
    if self.class.find_by(workout_id: workout_id, is_creator: true) 
     errors.add(:is_creator, 'can only have one creator') 
    end 
    end 
Смежные вопросы