APIDeveloperUserReleasesDemoContact
  • Core

    • Stores
    • Orders
    • Products
    • Payments
    • Shipments
    • Inventory
    • Promotions
    • Adjustments
    • Taxation
    • Calculators
    • Addresses
    • Preferences
  • Customization

    • Storefront
    • Templates
    • Assets (JS & CSS)
    • Images
    • Dependency system
    • Business Logic
    • Checkout Flow
    • Permissions
    • API v2
    • API v1
    • Authentication
    • Internationalization
    • Extensions
    • Emails
  • Security

    • Security
    • PCI Compliance
    • Authentication and Authorization
    • API
  • Source

    • About the Code
    • Getting Help
    • Navigating the Source
  • Tutorials

    • Getting Started with Spree
    • Add Spree to an existing Ruby on Rails application
    • Developing Spree
    • Improve SEO
    • Creating an Extension
    • Deface Overrides
    • Extend Product Attributes
    • Testing Spree Applications
    • Updating Extensions to Rails 6 and Spree 4
  • Upgrades

    • Upgrading Spree 4.1 to 4.2
    • Upgrading Spree 4.0 to 4.1
    • Upgrading Spree 3.7 to 4.0
    • Upgrading Spree from 3.6 to 3.7
    • Upgrading Spree from 3.5 to 3.6
    • Upgrading Spree from 3.4 to 3.5
    • Upgrading Spree from 3.3 to 3.4
    • Upgrading Spree from 3.2 to 3.3
    • Upgrading Spree from 3.1 to 3.2
    • Upgrading Spree from 3.0 to 3.1

Table Of Contents

Update your Ruby version to 2.5.0 at leastUpdate your Rails version to 6.0Migrate from Paperclip to ActiveStorageReplace class_eval with Module.prependReplace OrderContents with services in your codebaseOrderContents#update_cartOrderContents#addOrderContents#removeReplace add_store_credit_payments with Checkout::AddStoreCreditReplace remove_store_credit_payments with Checkout::RemoveStoreCreditRemove spree_address_book extensionRemove it from GemfileRemove it from vendor/assets/javascripts/spree/frontend/all.jsRemove it from vendor/assets/stylesheets/spree/frontend/all.cssUpdate GemfileRun bundle updateInstall missing migrationsRun migrationsRead the release notesMore info

Upgrading Spree 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.

  1. upgrade 3.2 to 3.3
  2. upgrade 3.3 to 3.4
  3. upgrade 3.4 to 3.5
  4. upgrade 3.5 to 3.6
  5. upgrade 3.6 to 3.7

This is the safest and recommended method.

Update your Ruby version to 2.5.0 at least

Spree 4.0 and Rails 6.0 require Ruby 2.5.0 at least so you need to bump the ruby version in your project’s Gemfile and .ruby-version files.

Update your Rails version to 6.0

Please follow the official Rails guide to upgrade your store.

Migrate from Paperclip to ActiveStorage

In Spree 3.6 we deprecated Paperclip support in favour of ActiveStorage. Paperclip gem itself isn’t maintained anymore and it is recommended to move to ActiveStorage as it is the defualt Rails storage engine since Rails 5.2 release.

In Spree 4.0 we completely removed Paperclip support in favour of ActiveStorage.

Also please remove any occurances of Rails.application.config.use_paperclip and Configuration::Paperclip in your codebase.

Please follow the official Paperclip to ActiveStorage migration guide

Replace class_eval with Module.prepend

Rails 6.0 ships with 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 - app/models/spree/order_decorator.rb

Spree::Order.class_eval do
  has_many :new_custom_model

  def some_method
     # ...
  end
end

New decorator - app/models/my_store/spree/order_decorator.rb

module MyStore
  module Spree
    module OrderDecorator
      def self.prepended(base)
        base.has_many :new_custom_model
      end

      def some_method
        # ...
      end
    end
  end
end

::Spree::Order.prepend(MyStore::Spree::OrderDecorator)

When migrating 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:

module Spree::BaseDecorator
  def spree_base_scopes
    # custom implementation
  end
end

Spree::Base.singleton_class.send :prepend, Spree::BaseDecorator

Please also consider other options for Logic Customization.

We recommend also reading through Ruby modules: Include vs Prepend vs Extend

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 coresponding services in your codebase.

OrderContents#update_cart

before:

order.contents.update_cart(line_items_attributes)

after:

Spree::Cart::Update.call(order: order, params: line_items_attributes)

OrderContents#add

before:

order.contents.add(variant, quantity, shipment: shipment)

after:

Spree::Cart::AddItem.call(
  order: order,
  variant: variant,
  quantity: quantity,
  options: {
    shipment: @shipment
  }
)

OrderContents#remove

before:

order.contents.remove(variant, quantity, shipment: shipment)

after:

Spree::Cart::RemoveItem.call(
  order: order,
  variant: variant,
  quantity: quantity,
  options: {
    shipment: shipment
  }
)

Replace add_store_credit_payments with Checkout::AddStoreCredit

Similar to OrderContents method add_store_credit_payments was replaced with Checkout::AddStoreCredit service.

before:

order.add_store_credit_payments

after:

Spree::Checkout::AddStoreCredit.call(order: order)

Replace remove_store_credit_payments with Checkout::RemoveStoreCredit

Similar to OrderContents method remove_store_credit_payments was replaced with Checkout::RemeoveStoreCredit service.

before:

order.remove_store_credit_payments

after:

Spree::Checkout::RemoveStoreCredit.call(order: order)

Remove spree_address_book extension

If you’re using Address Book extension you need to remove as this feature was merged into core Spree.

Remove it from Gemfile

Remove this line:

gem 'spree_address_book', github: 'spree-contrib/spree_address_book'

Remove it from vendor/assets/javascripts/spree/frontend/all.js

Remove this line if your’re using spree_frontend:

//= require spree/frontend/spree_address_book

Remove it from vendor/assets/stylesheets/spree/frontend/all.css

Remove this line if your’re using spree_frontend:

//= require spree/frontend/spree_address_book

Update Gemfile

gem 'spree', '~> 4.0'
gem 'spree_auth_devise', '~> 4.0'
gem 'spree_gateway', '~> 3.6'

Run bundle update

Install missing migrations

rails spree:install:migrations
rails spree_api:install:migrations
rails spree_auth:install:migrations
rails spree_gateway:install:migrations

Run migrations

rails db:migrate

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

Propose changes to this page
Maintained bySpree Commerce & Ruby on Rails developers© Spree Commerce. 2021 All Rights Reserved.