Association cache regression in Rails 6

9 views
Skip to first unread message

Andrew Kaspick

unread,
Dec 2, 2019, 8:38:11 PM12/2/19
to Ruby on Rails: Core
Hello,

I've found a regression in Rails 6 while upgrading my Rails 5.2 app that I'm sure is not correct behavior but I'd like a core member to confirm or not before I create a PR for it.  The root of the problem lies in the association cache in the internals of ActiveRecord.  The example below is the root of a more complex issue in my app, but the following is as basic as I can get to show the issue.
class Customer
  has_many :appointments
end

class Appointment
  belongs_to :customer
end
Example that works in Rails 5.2
a = Appointment.new customer_id: @customer.id
a.association(:customer).reader # returns @customer
Example that doesn't work in Rails 6.0
a = Appointment.new customer_id: @customer.id
a.association(:customer).reader # returns nil
Example that works in both Rails 5.2 and 6.0 (note the association is set without the id)
a = Appointment.new customer: @customer
a.association(:customer).reader # returns @customer
So is the example that doesn't work in Rails 6.0 a bug?  The example I provided isn't something you'll see in a Rails app, but Rails internals uses the association cache and if this is a bug, then fixing this would fix other potential issues.  Again, I found this issue due to a regression in my code with autosaved associations that I was setting via a foreign key parameter (ie. customer_id).

Andrew

Aaron Lipman

unread,
Dec 3, 2019, 9:55:38 AM12/3/19
to rubyonra...@googlegroups.com
Hi Andrew,

Afraid I'm not a Rails member, but I have been working on a couple caching-related bugs in Rails as of late. The behavior you're describing looks buggy, but I'm not quite able to replicate the issue from the example code you provided, so I'm having trouble understanding exactly where the discrepancy between Rails 5.2 and 6 is coming from. Would you be able to provide a failing executable test case, or explain in more detail the circumstances which trigger the behavior you're experiencing?

If useful, here's an executable test case I wrote as a starting point: https://gist.github.com/alipman88/d499739a466f3e6b6746eeccfa567f9a

(It may be practical to open an issue via GitHub and continue conversation there, moving forward.)

--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-co...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/rubyonrails-core/CAEUKiYHoddw6NySuH5sZ3GdOt-G4L3SsTfKUfcQioJHOnnrQ6Q%40mail.gmail.com.

Andrew Kaspick

unread,
Dec 3, 2019, 10:02:17 AM12/3/19
to Ruby on Rails: Core
Ok great, I'll take a look at your test case and see if I can provide a failing test.  Thanks for the reply.

Andrew Kaspick

unread,
Dec 3, 2019, 11:26:13 AM12/3/19
to Ruby on Rails: Core
Hi Aaron,

I've taken your example and provided a failing test case with a more elaborate example.  I've opened an issue at https://github.com/rails/rails/issues/37869 with a reference to an updated test case.

I wasn't able to get the example working in Rails 5.2 (the test was failing in Rails 5.2 as well), but the issue has only presented itself in Rails 6.0 in my apps use case.  The updated code in the test case is more in line with what's occurring in my application.  My app uses accepts_nested_attributes_for which sets autosave automatically, so in the test case, I just set autosave on the association in the test.  Also I use a custom save context which forces re-validation of the child association without the child association needing to be marked as dirty.

I also provided a "fix" that allows both test cases to pass (one fails and one passes right now).


On Tue, Dec 3, 2019 at 9:55 AM Aaron Lipman <alip...@gmail.com> wrote:
Reply all
Reply to author
Forward
0 new messages