From da8cd28e479d6052edd4e95e8123b12c1e6fdee0 Mon Sep 17 00:00:00 2001 From: JT Archie Date: Tue, 21 Jul 2026 12:40:33 -0600 Subject: [PATCH] Add RateStore#marshal_dump so a bank using it can be marshaled Money::Bank::VariableExchange#marshal_load rebuilds the store with store_info.shift.new(*store_info), which requires the store's #marshal_dump to return [StoreClass, *constructor_args]. Without it, marshaling a bank whose store is a RateStore fails, which happens when the configured default bank is cached under a Marshal-based serializer. RateStore takes no constructor arguments, so returning [self.class] is enough to rebuild it on load. --- CHANGELOG.md | 3 +++ lib/active_currency/rate_store.rb | 10 ++++++++++ spec/lib/active_currency/rate_store_spec.rb | 14 ++++++++++++++ 3 files changed, 27 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 81acbcf..cf6a245 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ This project adheres to [Semantic Versioning]. Changes: - Drop support for Rails < 7.0. +Fix: +- Make `RateStore` marshalable so a bank using it can be marshaled. + ## v1.4.1 Fix: diff --git a/lib/active_currency/rate_store.rb b/lib/active_currency/rate_store.rb index 19829c1..219a04a 100644 --- a/lib/active_currency/rate_store.rb +++ b/lib/active_currency/rate_store.rb @@ -3,5 +3,15 @@ module ActiveCurrency class RateStore < DatabaseStore include CacheableStore + + # Money::Bank::VariableExchange#marshal_load rebuilds the store with + # `store_info.shift.new(*store_info)`, so a store's #marshal_dump must + # return `[StoreClass, *constructor_args]`. RateStore takes no arguments, + # so returning `[self.class]` lets a bank backed by this store be + # marshaled -- for example when the configured default bank is cached + # under a Marshal-based cache/serializer. + def marshal_dump + [self.class] + end end end diff --git a/spec/lib/active_currency/rate_store_spec.rb b/spec/lib/active_currency/rate_store_spec.rb index a75c601..33f9ab5 100644 --- a/spec/lib/active_currency/rate_store_spec.rb +++ b/spec/lib/active_currency/rate_store_spec.rb @@ -104,4 +104,18 @@ end end end + + describe "#marshal_dump" do + it "dumps the class so the store can be rebuilt on load" do + expect(store.marshal_dump).to eq([described_class]) + end + + it "lets a bank backed by the store round-trip through Marshal" do + bank = Money::Bank::VariableExchange.new(store) + + loaded = Marshal.load(Marshal.dump(bank)) + + expect(loaded.store).to be_a(described_class) + end + end end