NathanB
NathanB

Reputation: 105

Prevent duplicate polymorphic records

I have a Rails 5 app with a Relations table. The table columns looks like:

fromable (polymorphic) toable (polymorphic)

I want to prevent users from saving relations that are duplicates (that is, that have the same fromable and toable). I've tried to do the following:

class Relation < ApplicationRecord

   ...

   belongs_to :fromable, polymorphic: true
   belongs_to :toable, polymorphic: true

   validate :is_not_duplicate_relation

   private

   def is_not_duplicate_relation
      errors.add(:base, "DUPLICATE") if Relation.where(toable: self.toable).where(fromable: self.fromable)
   end
end

But this seems to trigger invalid on everything?

Upvotes: 0

Views: 210

Answers (3)

Arpan Lepcha
Arpan Lepcha

Reputation: 176

You can also use .exists? if you are only checking for truthy or falsey. eg:

if Relation.exists?(toable: self.toable, fromable: self.fromable) errors.add(:base, "DUPLICATE") end

Upvotes: 1

Kiran Kumawat
Kiran Kumawat

Reputation: 92

You can use uniqueness validation instead of writing your own to handle this::

validates_uniqueness_of :fromable_id, scope: [:toable_id, :toable_type, :fromable_type], allow_nil: true

It will automatically check the combination of fromable and toable objects for uniqueness.

Upvotes: 1

Aleksei Matiushkin
Aleksei Matiushkin

Reputation: 121000

Relation.where(toable: self.toable).where(fromable: self.fromable) returns a relation object, which is always truthy.

You should explicitly check for it’s emptiness:

unless Relation.where(toable: self.toable).where(fromable: self.fromable).empty?

Upvotes: 0

Related Questions