docs/developer/upgrades/5.3-to-5.4.mdx
spree_sample gem from your GemfileSamples are now included in the spree gem. If you've added previously spree_sample to your Gemfile, remove it by running:
bundle remove spree_sample
bundle update
bin/rake spree:install:migrations && bin/rails db:migrate
Your admin user model needs to include the Spree::AdminUserMethods concern instead of Spree::UserMethods.
Previously UserMethods bundled AdminUserMethods but that caused all kinds of issues.
So if you have a model like this:
class Spree::AdminUser < Spree::Base
include Spree::UserMethods
# ... other model code ...
end
You need to change it to this:
class Spree::AdminUser < Spree::Base
include Spree::AdminUserMethods
# ... other model code ...
end
By default that file is located at app/models/spree/admin_user.rb.
Spree 5.4 adds a primary_media association to both Product and Variant models. This greatly speeds up rendering Product lists everywhere (API, Admin Dashboard and spree_storefront), as previously we've had to load all media/images for each product and determine which one is the one to render a thumbnail.
To generate the new association you will need to run a rake task (both in development and production environments):
bin/rails spree:media:backfill_primary_media
As above, this process can take a while depending on the size of your product catalog.
For new products this will be set automatically and you won't need to run this rake task more than once.
Spree 5.4 by default uses prefixed IDs for resources (eg. prod_6VsgxZbenF) instead of just IDs from the database. These IDs are now used in Admin Dashboard, API v3, Events system and Webhooks.
If you previously added Subscribers for Events, eg. order.completed with code such as:
module MyApp
class OrderAuditSubscriber < Spree::Subscriber
subscribes_to 'order.complete'
on 'order.complete', :log_order_completed
private
def find_order(event)
Spree::Order.find(event.payload[:id])
end
end
end
You will need to update your code to use the new prefixed IDs, from:
Spree::Order.find(event.payload[:id])
to:
Spree::Order.find_by_prefix_id!(event.payload[:id])
You can also use find_by_prefix_id without the bang (!) to gracefully handle cases where the record might not exist.
All models inheriting from Spree::Base (or Spree.base_class) can support Prefixed IDs by adding the following code to your model:
class MyModel < Spree::Base
has_prefix_id :mm
# ...
end
Prefix length isn't limited by default, but we recommend to keep it short.
Spree 5.4 introduces Markets as the primary way to manage which countries are available for checkout, along with their currencies and locales. The legacy checkout_zone field on the Store model is now deprecated and will be removed in Spree 6.0.
New stores automatically get a default market created from their default_country — no manual setup needed. For existing stores that used checkout_zone, run the migration rake task:
bin/rake spree:markets:migrate_checkout_zones
This will:
checkout_zone countries from each storecheckout_zone_id columnThe following Store methods now emit deprecation warnings and will be removed in Spree 5.5:
| Deprecated method | Replacement |
|---|---|
store.checkout_zone | Use Markets to manage countries |
store.checkout_zone= | Use Markets to manage countries |
The store.default_country reader now returns the first country (by name) from the store's default market. The store.default_country_iso= setter still works and is used to set the country when creating a store — a default market is automatically created from it.
checkout_zone for taxIf your application used store.checkout_zone as a tax zone fallback, update it to use Spree::Zone.default_tax instead:
# Before
zone = current_store.checkout_zone
# After
zone = Spree::Zone.default_tax
Spree 5.4 no longer depends on the activemerchant gem. All internal usages have been replaced with lightweight Spree-native classes:
| ActiveMerchant class | Spree replacement |
|---|---|
ActiveMerchant::Billing::Response | Spree::PaymentResponse |
ActiveMerchant::ConnectionError | Spree::PaymentConnectionError |
Spree::PaymentResponse is a drop-in replacement with the same constructor signature:
Spree::PaymentResponse.new(success, message, params = {}, options = {})
It supports the same methods: success?, message, params, authorization, avs_result, cvv_result, test?, and YAML serialization (for log entries).
If you have a custom payment method (gateway) that returns ActiveMerchant::Billing::Response, update it to return Spree::PaymentResponse instead:
# Before
def authorize(money, source, options = {})
# ...
ActiveMerchant::Billing::Response.new(true, 'Success', {},
authorization: transaction_id, test: test?)
end
# After
def authorize(money, source, options = {})
# ...
Spree::PaymentResponse.new(true, 'Success', {},
authorization: transaction_id, test: test?)
end
If your gateway rescues ActiveMerchant::ConnectionError, update it to rescue Spree::PaymentConnectionError:
# Before
rescue ActiveMerchant::ConnectionError => e
# After
rescue Spree::PaymentConnectionError => e
spree_gateway or other ActiveMerchant-based extensionsIf you use the spree_gateway gem or another extension that depends on ActiveMerchant, add activemerchant directly to your application's Gemfile:
gem 'activemerchant'
These extensions will continue to work — Spree's LogEntry#parsed_details still deserializes ActiveMerchant::Billing::Response objects when the gem is present.
Spree::Address#active_merchant_hash has been renamed to #gateway_hash. A backwards-compatible alias is provided, so existing code continues to work without changes.
Spree 5.4 ships with API v3, which marks deprecation of API v2. API v2 is still available but you need to install it separately. If you currently use API v2, you can do this by running the following command:
bundle add spree_legacy_api_v2
If you have tests for API v2 endpoints in your application, you will need to include some files in your rails_helper.rb:
require 'jsonapi/rspec'
require 'spree_legacy_api_v2/testing_support/v2/base'
require 'spree_legacy_api_v2/testing_support/factories'
require 'spree_legacy_api_v2/testing_support/v2/current_order'
require 'spree_legacy_api_v2/testing_support/v2/platform_contexts'
require 'spree_legacy_api_v2/testing_support/v2/serializers_params'
RSpec.configure do |config|
config.include JSONAPI::RSpec, type: :request # required for API v2 request specs
end
Also, add jsonapi-rspec gem to your Gemfile:
gem 'jsonapi-rspec', group: :test
And run bundle install
Multi-store features like multiple store management & custom domains were moved to a separate gem spree_multi_store.
If you rely on these features please run:
bundle add spree_multi_store
If you would like to use it in a commercial application, please contact us to obtain a commercial license. </Info>
Product Properties have been extracted from Spree core to a separate gem spree_legacy_product_properties. Product Properties were already deprecated in favor of Metafields and disabled by default since Spree 5.1.
If you have product_properties_enabled: true in your Spree configuration or rely on Product Properties in any way, install the extension:
bundle add spree_legacy_product_properties
No data migration is needed — the gem uses the same database tables. All existing product properties, property definitions, and associations will continue to work as before.
<Warning> If you skip this step and had Product Properties enabled, any code referencing `product.product_properties`, `product.property()`, `product.set_property()`, or the admin Properties page will stop working. </Warning>Posts and Post Categories management were extracted from Spree core into a separate gem spree_posts.
If you use these features before run this command to restore them:
bundle add spree_posts