3.7 to 4.0
This guide covers upgrading a 3.7 Spree application to Spree 4.0.
If you have any questions or suggestions feel free to reach out through Spree slack channels
If you're on an older version than 3.7 please follow previous upgrade guides and perform those upgrades incrementally, eg.
This is the safest and recommended method.

Update your Ruby version to 2.5.0 at least

Spree 4.0 requires Ruby 2.5.0 at least so you need to bump the ruby version in your project's Gemfile and .ruby-version files.

Migrate from Paperclip to ActiveStorage

In Spree 3.6 we deprecated Paperclip support in favor of ActiveStorage. Paperclip gem itself isn't maintained anymore and it is recommended to move to ActiveStorage as it is the default Rails storage engine since Rails 5.2 release.
In Spree 4.0 we've removed Paperclip support in favor of ActiveStorage.
Please remove also any occurrences of Rails.application.config.use_paperclip and Configuration::Paperclip from your codebase.

Replace OrderContents with services in your codebase

OrderContents was deprecated in Spree 3.7 and removed in 4.0. We've replaced it with service objects.
You need to replace any instances of OrderContents usage with corresponding services in your codebase.

OrderContents#update_cart

before:
1
order.contents.update_cart(line_items_attributes)
Copied!
after:
1
Spree::Cart::Update.call(order: order, params: line_items_attributes)
Copied!

OrderContents#add

before:
1
order.contents.add(variant, quantity, shipment: shipment)
Copied!
after:
1
Spree::Cart::AddItem.call(
2
order: order,
3
variant: variant,
4
quantity: quantity,
5
options: {
6
shipment: @shipment
7
}
8
)
Copied!

OrderContents#remove

before:
1
order.contents.remove(variant, quantity, shipment: shipment)
Copied!
after:
1
Spree::Cart::RemoveItem.call(
2
order: order,
3
variant: variant,
4
quantity: quantity,
5
options: {
6
shipment: shipment
7
}
8
)
Copied!

Replace add_store_credit_payments with Checkout::AddStoreCredit

Similar to OrderContents method add_store_credit_payments was replaced with Checkout::AddStoreCredit service.
before:
1
order.add_store_credit_payments
Copied!
after:
1
Spree::Checkout::AddStoreCredit.call(order: order)
Copied!

Replace remove_store_credit_payments with Checkout::RemoveStoreCredit

Similar to OrderContents method remove_store_credit_payments was replaced with Checkout::RemeoveStoreCredit service.
before:
1
order.remove_store_credit_payments
Copied!
after:
1
Spree::Checkout::RemoveStoreCredit.call(order: order)
Copied!

Remove spree_address_book extension

If you're using the Address Book extension you need to remove it as this feature was merged into core Spree.
    1.
    Remove this line from Gemfile
    1
    gem 'spree_address_book', github: 'spree-contrib/spree_address_book'
    Copied!
    2.
    Remove this line from vendor/assets/javascripts/spree/frontend/all.js
    1
    //= require spree/frontend/spree_address_book
    Copied!
    3.
    Remove this line from vendor/assets/stylesheets/spree/frontend/all.css
    1
    //= require spree/frontend/spree_address_book
    Copied!

Replace class_eval with Module.prepend (only for Rails 6)

Rails 6.0 ships with a new code autoloader called Zeitwerk which has some strict rules in terms of file naming and contents. If you used class_eval to extend and modify Spree classes you will need to rewrite those with Module.prepend. Eg.
Old decorator syntax - app/models/spree/order_decorator.rb
1
Spree::Order.class_eval do
2
has_many :new_custom_model
3
4
def some_method
5
# ...
6
end
7
end
Copied!
New decorator syntax - app/models/my_store/spree/order_decorator.rb
1
module MyStore
2
module Spree
3
module OrderDecorator
4
def self.prepended(base)
5
base.has_many :new_custom_model
6
end
7
8
def some_method
9
# ...
10
end
11
end
12
end
13
end
14
15
::Spree::Order.prepend(MyStore::Spree::OrderDecorator)
Copied!
When migrating a class method to the new autoloader things are a little different because you will have to prepend to the Singleton class as shown in this example:
1
module Spree::BaseDecorator
2
def spree_base_scopes
3
# custom implementation
4
end
5
end
6
7
Spree::Base.singleton_class.send :prepend, Spree::BaseDecorator
Copied!
Please also consider other options for Logic Customization.
We recommend also reading through Ruby modules: Include vs Prepend vs Extend

Update Bootstrap 3 to 4 or stay at Bootstrap 3

Spree 4 uses Bootstrap 4 for both Storefront and Admin Panel. You have two options:

Stay at Bootstrap 3

As we know this is a big portion of work you can still use Bootstrap 3 for your Storefront.
    1.
    Copy all remaining views by running bundle exec spree:frontend:copy_views
    2.
    Add bootstrap-sass gem to your Gemfile
    1
    gem 'bootstrap-sass', '~> 3.4.1'
    Copied!

Move to Bootstrap 4

Update Gemfile

1
gem 'spree', '~> 4.0'
2
gem 'spree_auth_devise', '~> 4.0'
3
gem 'spree_gateway', '~> 3.6'
Copied!

Run bundle update

Install missing migrations

1
rails spree:install:migrations
2
rails spree_api:install:migrations
3
rails spree_auth:install:migrations
4
rails spree_gateway:install:migrations
Copied!

Run migrations

1
rails db:migrate
Copied!

Read the release notes

For information about changes contained within this release, please read the 4.0.0 Release Notes.

More info

If you have any questions or suggestions feel free to reach out through Spree slack channels
Last modified 1mo ago