I have been through other questions, but the scenario is little different here:
class User < ApplicationRecord
has_many :documents, as: :attachable
validate :validate_no_of_documents
private
def validate_no_of_documents
errors.add(:documents, "count shouldn't be more than 2") if self.documents.size > 2
end
end
class Document < ApplicationRecord
belongs_to :attachable, polymorphic: true
validates_associated :attachable
end
Now, consider User.find(2)
that already has two documents, so doing the following:
user.documents << Document.new(file: File.open('image.jpg', 'rb'))
This successfully creates the document, and doesn't validate the attachable: User
. After the document is created in the database, both user
& Document.last
are invalid, but of what use, they have been created now.
I'm trying to create a Document
object on the run time, and that may be causing it, but for that purpose, I'm using size
instead of count
in my validation.
inverse_of
to rescue here again.
user = User.find(1) # This user has already 2 associated documents.
Doing user.documents << Document.new(file: file)
won't change the count for the associated documents of a user unless a document is actually created, and since the count will remain 2 while creating a 3rd document, so Rails won't stop you creating a third document associated with the user, killing the very purpose of putting the validation.
So following is what I did:
# In User model
has_many :documents, as: :attachable, inverse_of: :attachable
# In Document model
belongs_to :attachable, polymorphic: true, inverse_of: :attachments
Related article to read: https://robots.thoughtbot.com/accepts-nested-attributes-for-with-has-many-through