I've found some buggy behavior when caching & uncaching an array of 
ActiveRecord objects with ActiveStorage attachments. Here's a truncated 
code snippet demonstrating the bug:

class User < ActiveRecord::Base
  has_one_attached :avatar
end

users = User.first 5
users.each { |user| user.avatar }
Rails.cache.write "key", users
uncached_users = Rails.cache.read "key"

users[1]
# => :@attachment_changes

users[2]
# => {}

In the above code, every element of the array users is an instance of User. 
After writing to and reading from the cache, every element of uncached_users 
should 
still be an instance of User. However, after reading from the cache, the 
second and third elements of uncached_users are a symbol and empty hash. 
Here's a full executable test case: 
https://gist.github.com/alipman88/12928dfd2f86afacd1af51aeb8ae5194

After some digging, I've determined the underlying cause is a bug in Ruby 
itself, allowing instance variables to be added or removed during 
marshallization. (Many of Rails' cache stores use Marshal.load & 
Marshal.dump to serialize & deserialize objects.) While I'll skip over the 
specifics, the bug will be corrected in future implementations of Ruby. 
Here's the ticket on Ruby's issue tracker, for anyone seeking more detail: 
https://bugs.ruby-lang.org/issues/15968

Although future versions of Ruby will fix the underlying issue by raising 
a RuntimeError, this won't completely solve the problem: Rails developers 
may still encounter a somewhat confounding error without an immediately 
obvious cause.

I've submitted a pull request that fixes this issue by patching the 
delegate_missing_to extension through which this behavior arises: 
https://github.com/rails/rails/pull/36623

It's been a couple weeks since I submitted my pull request. Per advice in 
the Contributing to Ruby on Rails guide, I'm hoping to nudge things along 
and attract some code reviewers by posting here. I respect that Rails is a 
volunteer project, and appreciate any feedback when folks are able to 
provide it.

-- 
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-core+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/rubyonrails-core/67cac147-cb21-41e1-bbf8-25e1895c8fc0%40googlegroups.com.

Reply via email to