Module: RactorRailsShim::ActiveRecordStoreInstancePatch
- Defined in:
- lib/ractor_rails_shim/patches/active_record_store.rb
Overview
ActiveRecord::Store#store_accessor_for resolves the store coder via
type_for_attribute(store_attribute).tap do |type| ... end. The tap block
is compiled in the main Ractor and is un-shareable, so a worker Ractor raises
"defined with an un-shareable Proc in a different Ractor" when writing any
store accessor (e.g. ActiveStorage::Blob#identified=). Reimplement without
the block. This is an instance method of the ActiveRecord::Store module, so
it is prepended to ActiveRecord::Store itself.
Instance Method Summary collapse
- #store_accessor_for(store_attribute) ⇒ Object
-
#write_store_attribute(store_attribute, key, value) ⇒ Object
ActiveRecord::Store::HashAccessor#writemutates the hash returned byobject.<attribute>and relies on that read returning a cached, mutable object so the mutation is reflected on later reads.
Instance Method Details
#store_accessor_for(store_attribute) ⇒ Object
124 125 126 127 128 129 130 |
# File 'lib/ractor_rails_shim/patches/active_record_store.rb', line 124 def store_accessor_for(store_attribute) type = type_for_attribute(store_attribute) unless type.respond_to?(:accessor) raise ConfigurationError, "the column '#{store_attribute}' has not been configured as a store. Please make sure the column is declared serializable via 'ActiveRecord.store' or, if your database supports it, use a structured column type like hstore or json." end type.accessor end |
#write_store_attribute(store_attribute, key, value) ⇒ Object
ActiveRecord::Store::HashAccessor#write mutates the hash returned by
object.<attribute> and relies on that read returning a cached, mutable
object so the mutation is reflected on later reads. In a worker Ractor the
serialized attribute read is not cached (each read re-deserializes), so the
in-place mutation is lost and store accessors such as
ActiveStorage::Blob#identified= silently fail to persist. Re-implement
write_store_attribute to read the current value, merge the key, and write
it back through write_attribute — which always persists regardless of
whether the deserialized read is cached. Store accessors use string keys,
so the key is normalized with to_s.
142 143 144 145 146 147 |
# File 'lib/ractor_rails_shim/patches/active_record_store.rb', line 142 def write_store_attribute(store_attribute, key, value) current = read_attribute(store_attribute) current = current ? current.dup : {} current[key.to_s] = value write_attribute(store_attribute, current) end |