rails
rails copied to clipboard
AR is erroneously validating existing records on a has_many :through
Its Friday, so entirely possible I just need a drink and some sleep. But after upgrading a legacy app to the latest and greatest, I've started to see unexpected validations when creating new records with existing associations on a has_many :through
.
See attached gist: https://gist.github.com/uberllama/1d0323438700d4f23bbb
I have a Conversation class, which has many :users
through :conversation_users
. When a user creates a new Conversation, they specify which Users they want to include in the Conversation. This boils down to:
class Conversation < ActiveRecord::Base
has_many :conversation_users
has_many :users, through: :conversation_users
end
class ConversationUser < ActiveRecord::Base
belongs_to :conversation
belongs_to :user
end
class User < ActiveRecord::Base
has_many :conversation_users
has_many :conversations, through: :conversation_users
validates :name, presence: true
end
conversation = Conversation.new(user_ids: [1,2,3])
conversation.save
When calling save
on the new Conversation instance, AR is validating the associated Users even though they are existing, non-dirty objects. This results in huge amounts of unnecessary weight on every Conversation save. It should not be the responsibility of a model to validate its associated objects unless those objects are being created or modified along with the parent model.
What am I missing?
Have you tried skipping callbacks to narrow down where the validations might be occurring?
I haven't no. I just confirmed this is still an issue in 4.2.
@uberllama you said you're upgrading a legacy app. Is this a regression? If so, from which versions?
@tenderlove From 3.2.18 :( No going back to that one! I also can't guarantee that it wasn't happening in Rails 3, only that I hadn't recalled seeing it before.
When owner of association is a new record, then all associated records would be validated. This behavior dates at least to 2009: https://github.com/rails/rails/commit/5cda000bf0f6d85d1a1efedf9fa4d0b6eaf988a1#diff-829fd5510b886395117cc530518ef7f7R211
So its a 5 year old problem... :)
@uberllama yes it is a 5 year old issue. I had a fix for this issue that passes in Active Record but I broke the Active Model tests. Working towards a solution that works in both. :grin: I'll update you when I have one.
Bless your heart.
Giant hugs all around.
I have to revert the change that fixed this. I realize it's been a year but this hasn't been in any released version of Rails and a few issues have come up since Rails 5 has been in beta. I don't want this to delay the RC since the bugs my change introduced are worse than this one. I'm reopening this so I can try to fix it without breaking valid?
on persisted records.
For what it's worth, this is causing issues for us.
Even today facing the same issue...
Is there a workaround for this?