Skip to content

Instantly share code, notes, and snippets.

@swrobel
Last active December 18, 2018 16:48
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save swrobel/6343549 to your computer and use it in GitHub Desktop.
Save swrobel/6343549 to your computer and use it in GitHub Desktop.
HOWTO: Upgrade Spree 1.3.3 to 2.0.4

HOWTO: Upgrade Spree 1.3.3 to 2.0.4

These steps were sufficient to upgrade Cult Cosmetics to Spree 2.0.4 from 1.3.3. Here are some details on our environment.

  • We only have single-variant products
  • We are not making use of stock locations (single warehouse)
  • Frontend entirely overridden w/ custom bootstrap layout
  • Braintree gateway
  • Rails 3.2.14
  • Upgraded from Ruby 1.9.3-p448 to 2.0.0-p247 in the process (no issues)

Pull requests are encouraged to update this with steps that I missed!

Lessons learned (the hard way)

  1. MailMethods have been refactored. This breaks your existing mail config.
  2. Shipping Calculators have been refactored. This breaks your existing shipping calculators.
  3. Shipping Category is now required for all products and shipping methods. Checkout will just stop at the delivery step with no explanation if you don't have this configured.
  4. Lots has been changed in the frontend code, which has been refactored out into the spree_frontend gem. If you're overriding the views, there is plenty more to do that I'll document later, although I probably only scratched the surface.

Steps I followed

  1. Update Spree and extensions in your Gemfile
gem 'spree', '~> 2.0.4'
# Should work for most extensions
gem 'spree_gateway', github: 'spree/spree_gateway', branch: '2-0-stable'
  1. bundle install (or just bundle if you're super-cool)
  2. bundle exec rake railties:install:migrations && bundle exec rake db:migrate
  3. Edit app/assets/javascripts/admin/all.js
-//= require admin/spree_core
-//= require admin/spree_promo
+//= require admin/spree_backend
  1. Edit app/assets/javascripts/store/all.js
-//= require admin/spree_core
-//= require admin/spree_promo
+//= require admin/spree_backend
  1. Edit app/assets/stylesheets/admin/all.css
- *= require admin/spree_core
- *= require admin/spree_promo
+ *= require admin/spree_backend
  1. Edit app/assets/stylesheets/admin/all.css
- *= require admin/spree_core
- *= require admin/spree_promo
+ *= require admin/spree_frontend
  1. Shipments need a stock location and your existing shipments won't have one. rails g migration AddStockLocationToShipments

Should contain: (obviously this is more complicated if you're actually planning on using multiple Stock Locations)

location = Spree::StockLocation.find_by_name('default')
Spree::Shipment.update_all(stock_location_id: location.id)
  1. You need a Shipping Category if you don't already have one (they weren't required before 2.0). Every Product && Shipping Method needs a shipping category assigned to it as well. rails g migration CreateDefaultShippingCategory

Should contain: ```ruby default_category = Spree::ShippingCategory.first default_category ||= Spree::ShippingCategory.create!(:name => "Default")

Spree::ShippingMethod.all.each do |method|
  method.shipping_categories << default_category if method.shipping_categories.blank?
end

Spree::Product.where(shipping_category_id: nil).update_all(shipping_category_id: default_category.id)
```
  1. New Products also need a shipping category but this isn't obvious in the Admin. I chose to set it before a new Product is created in app/controllers/admin/products_controller_decorator.rb

    Spree::Admin::ProductsController.class_eval do
    
      new_action.before :set_shipping_category
    
      private
    
      def set_shipping_category
        @product.shipping_category = Spree::ShippingCategory.first # or whichever category your heart desires
      end
    end
  2. This one is a doozy. Spree 2.0 uses new Shipping Calculators that are separate from the old Spree::Calculator classes. This insane migration will recreate your calculators using the new models and copy over your old preferences. rails g migration MigrateOldShippingCalculators

    Spree::ShippingMethod.all.each do |shipping_method|
      old_calculator = shipping_method.calculator
      next if old_calculator.class < Spree::ShippingCalculator # We don't want to mess with new shipping calculators
      new_calculator = eval("Spree::Calculator::Shipping::#{old_calculator.class.name.demodulize}").new
      new_calculator.preferences.keys.each do |pref|
        # Preferences can't be read/set by name, you have to prefix preferred_
        pref_method = "preferred_#{pref}"
        new_calculator.send("#{pref_method}=", old_calculator.send(pref_method))
      end
      new_calculator.save
      shipping_method.calculator = new_calculator
    end

See this comment if you have custom shipping calculators: https://gist.github.com/swrobel/6343549#comment-918763

  1. Mail Methods have also been refactored, breaking your existing mail config. I prefer to just set up the ActionMailer config in my environment config files (production.rb, development.rb, etc) and use the new setting to prevent spree from overriding ActionMailer like so:

    # config/initializers/spree.rb
    Spree.config do |config|
      config.override_actionmailer_config = false
      config.mails_from = 'Your Company <mail@yourcompany.com>'
      # Set domain for emails
      ActionMailer::Base.default_url_options[:host] = config.site_url
    end

Otherwise, just make sure to go into the Admin and set up your Mail config again for 2.0

  1. Replace any instances of t(:translation) in your code with Spree.t(:translation)

  2. If you were using the Spree::Config.show_zero_stock_products = false option, use my extension to bring it back:

gem 'spree_zero_stock_products'
```ruby
# config/initializers/spree.rb
Spree.config do |config|
  config.show_zero_stock_products = false # Default is true
end
```
  1. If you were using the Spree::Config.allow_backorders = false option, rails g migration SetBackorderableToFalse:
Spree::StockItem.update_all(backorderable: false)
Spree::StockLocation.update_all(backorderable_default: false)
@brchristian
Copy link

@swrobel Thanks for such a handy guide!

Your asset updates seem a little confusing to me. For instance, in Step 5 for app/assets/javascripts/store/all.js, you list—

-//= require admin/spree_core
+//= require admin/spree_backend

—but I would expect to see store/spree_core rather than admin/spree_core, given the filename.

In Step 7 for app/assets/stylesheets/admin/all.css you discuss changing—

- *= require admin/spree_core
+ *= require admin/spree_frontend

—but I would expect admin/spree_backend rather than admin/spree_frontend. (Is there an 'admin frontend'?)

I might be confused here, or this might be a typo.

@bbuchalter
Copy link

@brchristian did you ever determine whether the asset modifications were typos or not?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment