Rails validating uniqueness of polymorphic association

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?

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

Rails validating uniqueness of polymorphic association, validates :member_id, :uniqueness => { :scope => [:member_type, :group_id,: group_type] }. With this, you might also want to make presence of� As mentioned briefly above, as well as using this validation in your model you should ensure the underlying database table also has a unique index to avoid a race condition. For example: class User < ActiveRecord:: Base validates_uniqueness_of:login_name end. The index can be specified in the migration for the User model using add_index like this:

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

validate uniqueness of polymorphic association, I think you can use Conditional Validation. Sometimes it will make sense to validate an object only when a given predicate is satisfied. You can do that by using� Ruby on Rails. Contribute to rails/rails development by creating an account on GitHub. …scope-with-polymorphic-association fix the uniqueness validation scope with a polymorphic association

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

Uniqueness validation scope with polymorphic association � Issue , Uniqueness validation scope with polymorphic association #31010 r? @kaspth . (@rails-bot has picked a reviewer for you, use r? to override). You should use has_many :through if you need validations, callbacks, or extra attributes on the join model. 2.9 Polymorphic Associations. A slightly more advanced twist on associations is the polymorphic association. With polymorphic associations, a model can belong to more than one other model, on a single association.

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

Polymorphic Associations, Codecabulary Home / Learn Rails / Polymorphic Associations to allow a single user to like a single thing only once, we'll validate uniqueness of the userid,� Limiting the unique indexes to only not null values dramatically saves space as well as reducing write operations on insert. How to Choose. I usually dismiss a polymorphic join immediately due to its lack of data integrity guarantees. The only advantage it has is an ORM such as Rails' ActiveRecord may make it very easy to use.

validates_uniqueness_of (ActiveRecord::Validations::ClassMethods , Ruby on Rails latest stable (v5.2.3) - 4 notes - Class: Validates whether the value of the specified attributes are unique across the system. class Bookmark < ActiveRecord::Base belongs_to :thing, :polymorphic => true belongs_to :owner, � Taking the following classes: class User < ActiveRecord::Base has_one :address, :as => :addressable accepts_nested_attributes_for :address end class Address

The Perils of Uniqueness Validations, When you persist a user instance, Rails will validate your model by running a searches do not properly recognize polymorphic relationships. Active Record Associations are one of the most important features of Rails. Polymorphic association is part of these associations. Ruby on Rails Guidestates “with polymorphic associations, a model can belong to more than one other model, on a single association”.

4 Ways to Model Polymorphic Associations in Rails 5, 4 Ways to Model Polymorphic Associations in Rails 5 There's two ways to enforce the exclusive constraint: ActiveRecord validations or a custom In order to enforce the one to many relationship we'll add a unique� Active Record ValidationsThis guide teaches you how to validate the state of objects before they go into the database using Active Record's validations feature.After reading this guide, you will know: How to use the built-in Active Record validation helpers.

Comments
  • I just have tried this code in Rails 5.0 and received the same error. Also I tried in Rails 5.1 and the code works fine, no errors.
  • Thanks this won't do it though because like I said, my model is doubly polymorphic. meaning each member id identified by member_type (which can be User, Organisation, Network) and member_id..... So I wrote my own custom method, see my answer. Cheers anyway.
  • This prevents me from updating the record. Did you also experience it? Adding validate :member_is_unique_for_group, on: :create worked
  • This approach creates a race condition, see the end of this paragraph: guides.rubyonrails.org/… > Note that checking for uniqueness using something like include? is subject to race conditions. Do not attempt to use include? to enforce distinctness in an association.