Reputation: 34643
I have the following:
class Membership < ApplicationRecord
belongs_to :member, polymorphic: true
belongs_to :group, polymorphic: true
end
As you can see my Membership model is doubly polymorphic. I want to validate the uniqueness of :member
scoped by :group
.
I was hoping the following would work:
validates :member, uniqueness: { scope: :group }
But this causes an error:
NameError: uninitialized constant Membership::Member
Is there a Rails way of doing this, or do I need to write a custom method for it?
Upvotes: 2
Views: 1388
Reputation: 310
I ended up with this. (on: :create
allows updating)
validate :group_member_uniqueness, on: :create
def group_member_uniqueness
if Membership.where(group: group, member: member).exists?
errors[:base] << 'That has already been added'
end
end
DB index
add_index :memberships, [:group_id, :group_type, :member_id, :member_type], unique: true
Upvotes: 0
Reputation: 310
I used rohan's answer but added another validation for group_id
validates :group_id, uniqueness: { :scope => [:group_type, : member_id,: member_type] }
validates :member_id, uniqueness: { :scope => [:member_type, : group_id,: group_type] }
I also added a DB index
add_index :memberships, [:group_id, :group_type, :member_id, :member_type], unique: true
Upvotes: 0
Reputation: 34643
There is no built-in for this, so I did the following:
validate :member_is_unique_for_group
def member_is_unique_for_group
if group.members.include? member
errors.add(:member, 'already exists for this group')
end
end
Upvotes: -1
Reputation: 1656
validates :member_id, :uniqueness => { :scope => [:member_type, :group_id,:group_type] }
With this, you might also want to make presence of member and group both mandatory, as nil values will lead to duplicates and will fail the uniqueness validation
validates :member_type, :member_id, :presence => true
validates :group_type, :group_id, :presence => true
Upvotes: 2