I have 3 models in my rails application, User, Course, and CourseTemplate.
A Course belongs to a User and a CourseTemplate belongs to a Course.
What I want to do is to validate the uniqueness between the CourseTemplate name and the User id.
Is this possible?
class CourseTemplate < ActiveRecord::Base
belongs_to :course
has_one :user, through: :course
validate :unique_course_template_for_user
private
def unique_course_template_for_user
errors.add(:name, 'Must be unique') if CourseTemplate.find_by(user: user.id, name: self.name).count > 0
end
end
If you're ok with some denormalization of your data, you could add user_id
to CourseTemplate, and then simply use the scope feature of validates uniqueness.
Below I show how to use callbacks to maintain the user_id in the CourseTemplate. Note that it assumes a course cannot be moved to a different user.
class CourseTemplate < ActiveRecord::Base
before_create :copy_user_id_from_course
validates :name, uniqueness: { scope: :user_id, message: 'Must be unique for the same user'}
private
def copy_user_id_from_course
self.user_id = course.user_id
true
end
end
If the course can be moved to a different user, you should add a callback on Course:
class Course < ActiveRecord::Base
after_save :set_course_templates_user, if: :user_id_changed?
private
def set_course_templates_user
course_templates.update_all user_id: self.user_id
end
end