rails icon indicating copy to clipboard operation
rails copied to clipboard

AR is erroneously validating existing records on a has_many :through

Open uberllama opened this issue 9 years ago • 13 comments

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?

uberllama avatar Nov 14 '14 16:11 uberllama

Have you tried skipping callbacks to narrow down where the validations might be occurring?

jcutrell avatar Dec 06 '14 17:12 jcutrell

I haven't no. I just confirmed this is still an issue in 4.2.

uberllama avatar Jan 04 '15 02:01 uberllama

@uberllama you said you're upgrading a legacy app. Is this a regression? If so, from which versions?

tenderlove avatar Jan 06 '15 18:01 tenderlove

@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.

uberllama avatar Jan 06 '15 18:01 uberllama

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

brainopia avatar Jan 06 '15 19:01 brainopia

So its a 5 year old problem... :)

uberllama avatar Jan 07 '15 14:01 uberllama

@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.

eileencodes avatar Jan 16 '15 14:01 eileencodes

Bless your heart.

uberllama avatar Jan 16 '15 14:01 uberllama

Giant hugs all around.

uberllama avatar Feb 02 '15 01:02 uberllama

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.

eileencodes avatar Feb 23 '16 20:02 eileencodes

For what it's worth, this is causing issues for us.

bigmountainben avatar Jul 08 '18 00:07 bigmountainben

Even today facing the same issue...

alfie-max avatar Jul 30 '20 12:07 alfie-max

Is there a workaround for this?

cdimitroulas avatar Jul 29 '22 09:07 cdimitroulas