Upgrade Notes
General upgrade process
Back up your database and code
Always advisable!
Perform the standard upgrade command
spree —update
Remove obsolete initializers
rm -rf config/initializers/compass.rb
h5. Remove defunct contents of public dirs
rm -rf public/javascripts/ rm -rf public/stylesheets/ rm -rf public/images/
Take note of existing payment gateway settings
The new payment gateway implementation will remove existing settings, and these need to be added again using the new interface.
Run the migrations
rake db:migrate
Configure a payment method
See the additional information later in the release notes.
Deprecation Warnings
The newer version of Rails used by Spree generates a lot of deprecation warnings. You may see the following message in your console:
DEPRECATION: require "activerecord" is deprecated and will be removed in Rails 3. Use require "active_record" instead.
Remove all instances of require 'activerecord'
from your Rakefiles
API Changes
Change to taxonomies
variable
Taxonomies
used to be set in most shared views. Now, it is only set
after calling get_taxonomies
(inherited from Spree’s base
controller).
Spree Base Controller and Layouts
Spree::BaseController
inherits directly from ActionController::Base
,
rather than from ApplicationController
(which itself is now an empty
class to help interaction with other Rails apps).
If you used app/views/layout/application.html.erb
in an extension.
e.g.
Spree::BaseController.class_eval { layout 'application' }
… then you will need to rename it to spree_application.html.erb
and
update the occurrences.
Adding admin tabs changed
extension_tabs
is no longer used, instead use theme “hooks”:hooks.html.
Theme Support
Spree now has basic support for theming. Themes in Spree are implemented as “extensions”:extensions.html. All of the default views in Spree have now been abstracted into a default theme. You can override all or parts of the default theme in a new theme. Themes have their own generator and are created as follows:
script/generate theme foo
You can read more about themes in the very extensive customization guide
Don’t panic if you have already customized Spree views in your site extension for a previous release of Spree. These view customizations should continue to work as long as they are loaded after the default theme extension.
Named Scopes and Product Groups
In various applications, we need to create lists of products according to various criteria, e.g. all products in taxon X, or all products costing less than $20, or composite criteria like all products costing more than $100 that have brand Y. Spree provides several so-called named scopes, which provide filtering by various aspects of the basic data, some of which can be chained or composed together for more complex filters.
Named scopes can also be combined. The following chain of scopes lists the products that are active and with a price between $18 and $20.
Product.active.price_between(18,20)
Product groups allow for the defining and naming groups of products for various purposes in an application. For example, you can define a group called Ruby products which contains everything with Ruby in the product name, or another group called Ruby clothing which is the sub-list of the above limited to items in the Clothing taxon. Product group definitions can also take price ranges, product properties, and variant options into account. It is possible to add your own filters by defining new named scopes too.
Please see the documentaiton for a more complete explanation of named scopes and product groups.
Improvements to Payment Gateway Configuration
This release contains significant improvements to how payment gateways are configured. Gateways are no longer supported by database migrations, this scheme has been replaced by Active Record models that extend Gateway
. The configuration of gateways is now done through standard Spree preference configuration
. The documentation has also been updated and contains a more detailed explanation.
One major improvement is that it is now possible to configure multiple gateways for each of your Rails environments. Its also possible to use the live production server in development mode when previously, you were required to run in test mode. One unfortunate side effect of this improvement is that your existing gateway configuration information will be lost and you will need to reconfigure your gateway in the admin interface.
You should make a note of your gateway configuration setting before upgrading since you will need to reconfigure your gateway when you’re done.
This approach to implementing and configuring gateways is extremely flexible. It makes it trivial to implement a new gateway that is already supported by Active Merchant. There are other useful benefits to this approach that a developer may be interested in knowing.
Support of Non Active Merchant Gateways
This architecture allows Spree to support gateways that are not officially supported by Active Merchant. Many times a new gateway is donated by someone in the community but its languishing in the queue waiting for someone to test and accept the patch. You have the option of taking that code (or writing your own from scratch) and implementing it within Spree. Instead of delegating to an Active Merchant class, you can simply implement that functionality yourself. You could also include the new gateway code from an Active Merchant fork inside your implementation and delegate the standard authorize, capture, etc operations to it.
Ability to “Patch” Active Merchant Gateways
We’ve noticed that sometimes it takes a while for a crucial Active Merchant patch to be applied. That’s certainly understandable, the Shopify guys have a business to run and its probably not a high priority for them to make sure that the latest obscure gateway patch is applied in a timely fashion. Fortunately, the Spree approach to wrapping these gateways provides you with a convenient option.
Lets say there is a bug with the +authorize+ method. You could simply provide an implementation of the gateway that has the patched version of the authorize
method and then delegates to the Active Merchant class for everything else (since that works just fine.)
Additional Functionality Beyond Active Merchant
Another benefit of the architecture is that it makes it possible for Spree to provide additional common functionality that was not envisioned by Active Merchant. Specifically, it is possible to provide an abstraction for storing credit card profiles to be used with recurring payments. There’s a good reason for Active Merchant to not care about this functionality. Its designed for people who just want to drop a single gateway provider into their application. Most programmers don’t need three different gateways at once. Spree is a specialized use case. Its providing multiple gateways for you to choose from and so its desirable to have a standard method for operations such as this.
Recurring payments are not yet supported in Spree although there are plans to provide this in the near future.
Multi Step Checkout
Checkout Steps
Spree has returned to a multi step checkout process. The following checkout steps are defined by default.
- Registration (Optional)
- Address Information
- Delivery Options (Shipping Method)
- Payment
- Confirm
There is also a default progress “train” which shows the current step and allows you to jump back to a previous step by clicking on it.
If you have a site running on a previous verison of Spree, your checkout process will likely need to be upgraded. The good news is the new approach is much easier to customize.
The checkout process is highly customizable - in fact, this is the reasoning behind moving away from the single step checkout. There is far less code hidden in javascript and each checkout step has its own partial. See the checkout documentation for mor information on how to customize the checkout.
Countries Available for Shipping and Billing
The mechanism for determining the list of billing and shipping countries has changed. Prior to this release, there was no way to limit the billing countries and shipping countries were limited by the countries included in the shipping zones that were configured. The new approach is to simply use all countries defined in the database by default.
The list can be limited to a specific set of countries by configuring the new :checkout_zone
preference and setting its value to the name of a zone containing the countries you wish to use. This should handle most cases where the list of billing and shipping countries are the same. You can always customize the code via extension if this does not suit your needs.
State Machine
The Checkout model now has its own state machine. This allows for easier customization of the checkout process. It is now much simpler to add or remove a step to the default checkout process. Here’s an example which avoids the address step in checkout.
class SiteExtension < Spree::Extension def activate # customize the checkout state machine Checkout.state_machines[:state] = StateMachine::Machine.new(Checkout, :initial => 'payment') do after_transition :to => 'complete', :do => :complete_order before_transition :to => 'complete', :do => :process_payment event :next do transition :to => 'complete', :from => 'payment' end end # bypass creation of address objects in the checkouts controller (prevent validation errors) CheckoutsController.class_eval do def object return `object if `object `object = parent_object.checkout unless params and params[:coupon_code] `object.creditcard ||= Creditcard.new(:month => Date.today.month, :year => Date.today.year) end `object end end end end
Controller Hooks
The*CheckoutController+ now provides its own “hook mechanism” (not to be
confused with theme hooks) which allow for the developer to perform
additional logic (or to change the default) logic that is applied during
the edit and/or update operation for a particular step. The
Spree::Checkout::Hooks
module provides this additional functionality
and makes use of methods provided by the resource_controller
gem.
See the checkout documentation for
further details and examples.
Checkout Partials
The default theme now contains several partials located within
vendor/extensions/theme_default/app/views/checkouts
. Each checkout
step automatically renders the edit.html.erb
view along with a
corresponding partial based on the state associated with the current
step. For example, in the delivery step the _delivery.html.erb
partial is used.
Javascript
Spree no longer requires javascript for checkout but the user experience
will be slightly more pleasing if they have javascript enabled in their
browser. Spree automatically includes the checkout.js
file located in
the default theme. This file can be replaced in its entirety through use
of a site extension.
Payment Profiles
The default checkout process in Spree assumes a gateway that allows for some form of third party support for payment profiles. An example of such a service would be Authorize.net CIM. Such a service allows for a secure and PCI compliant means of storing the users credit card information. This allows merchants to issue refunds to the credit card or to make changes to an existing order without having to leave Spree and use the gateway provider’s website. More importantly, it allows us to have a final “confirmation” step before the order is processed since the number is stored securely on the payment step and can still be used to perform the standard authorization/capture via the secure token provided by the gateway.
Spree provides a wrapper around the standard active merchant API in
order to provide a common abstraction for dealing with payment profiles.
All Gateway
classes now have a payment_profiles_supported?
method
which indicates whether or not payment profiles are supported. If you
are adding Spree support to a Gateway
you should also implement the
create_profile
method. The following is an example of the
implementation of create_profile
used in the AuthorizeNetCim
class:
# Create a new CIM customer profile ready to accept a payment def create_profile(creditcard, gateway_options) if creditcard.gateway_customer_profile_id.nil? profile_hash = create_customer_profile(creditcard, gateway_options) creditcard.update_attributes(:gateway_customer_profile_id =\> profile_hash[:customer_profile_id], :gateway_payment_profile_id =\> profile_hash[:customer_payment_profile_id]) end end
Most gateways do not yet support payment profiles but the
default checkout process of Spree assumes that you have selected a
gateway that supports this feature. This allows users to enter credit
card information during the checkout withou having to store it in the
database. Spree has never stored credit card information in the database
but prior to the use of profiles, the only safe way to handle this was
to post the credit card information in the final step. It should be
possible to customize the checkout so that the credit card information
is entered on the final step and then you can authorize the card before
Spree automatically discards the number while saving the Creditcard
object.
Seed and Sample Data in Extensions
Seed data is data that is needed by the application in order for it to
work properly. Seed data is not the same as sample data. Instead of
loading this type of data in a migration it is handled through the
standard rails task through rake db:seed
. The rake task will first
load the seed data in the spree core (ex. db/default/countries.yml
.)
Spree will then load any fixtures found in the db/default
directory of
your extensions. If you wish to perform a seeding function other than
simply loading fixtures, you can still do so in your extension’s
db/seeds.rb
file.
Sample data is data that is convenient to have when testing your code.
Its loaded with the rake db:sample
task. The core sample data is
loaded first, followed by any fixtures contained in the db/sample
directory of your extensions.
If you have fixtures in your extension with the same filename as those found in the core, they will be loaded instead of the core version. This applies to both sample and seed fixtures. This allows for fine grained control over the sample and seed data. For example, you can create your own custom sample order data in your site extension instead of relying on the version provided by Spree.
You should remove all db:bootstrap
tasks from your
extensions. The new bootstrap functionality in the core will
automatically load any fixtures found in db/sample
of your extension.
Failing to remove this task from your extension will result in an
attempt to create the fixtures twice.
RESTful API
The REST API is designed to give developers a convenient way to access data contained within Spree. With a standard read/write interface to store data, it is now very simple to write third party applications (ex. iPhone) that can talk to Spree. The API currently only supports a limited number of resources. The list will be expanded soon to cover additional resources. Adding more resources is simply a matter of making the time for testing and investigating possible security implications. See the REST API section for full details.
Inventory
Inventory modeling has been modified to improve performance. Spree now
uses a hybrid approach where on-hand inventory is stored as a count in
Variant#on_hand
, but back-ordered, sold or shipped products are
stored as individual InventoryUnits
so they can be tracked.
This improves the performance of stores with large inventories. When the
on_hand
count is increased using Variant#on_hand=
, Spree will
first fill back-orders, converting them to InventoryItems
, then place
the remaining new inventory as a count on the Variant
model. A
migration is in place that will convert on-hand InventoryItems
to a
simple count during upgrade. Due to an issue with the sample data, demo
stores cannot be upgraded in this fashion and should be re-bootstrapped.
Miscellaneous improvements
Sample Product Images in Extensions
For some time now you’ve been able to write sample data fixtures in
extensions
that will get run when you load sample data with the rake db:bootstrap
task.
Now you can also add sample product image files in your extensions in
the
extensions own lib/tasks/sample/products
directory. These images will
be
copied to the public/assets/products
directory when the sample data is
loaded.
Additional information on the release can be found in the
CHANGELOG
file as well as the official ticket
system.
Ruby 1.9 Support
Spree is now 100% Ruby 1.9 compatible. There are a few workarounds
needed to achieve this and those are consolidated in a custom
initializer appropriately named workarounds_for_ruby19
.
Sales Overview
The default admin screen now shows a series of tables and graphs related to recent sales activity. By consulting this screen you can now see the following information
- Best Selling Products
- Top Grossing Products
- Best Selling Taxons
- Information on the Last 5 Orders
- Biggest Spenders
- Out of Stock Products
- Order Count by Day
Extension Load Order
It is now recommended to define the extension load order outside of the
environment.rb
file. This makes it easier for you to use the standard
environment.rb
file that comes with Spree and thus easier to upgrade.
To define the extension load order inside of an initializer you can use
the following line of code:
SPREE_EXTENSIONS_LOAD_ORDER = [:theme_default, :all, :site]
SEO Improvements
Products and taxons are now available by a single URL only. Prior to this release both of these URL’s returned the same result:
- http://localhost:3000/products/ruby-on-rails-ringer-t-shirt/
- http://localhost:3000/products/ruby-on-rails-ringer-t-shirt
Now we are returning a 301
redirect for the version of the URL without
the trailing ‘/’ character. Some SEO experts seem to feel that
inconsistent links and links without a trailing slash can be
penalized
We’ve been asked by one of our clients to fix this. We’re passing on the
SEO improvements to you!
Multiple Forms of Payment
Spree now supports multiple forms of payment. This support is in the early stages but the basic build blocks are now present so that it should be quite easy to allow additional forms of payment. More documentation and improvements in this area are coming.
Refunds and Credits
Spree now has explicit support for refunds and credits. More details to follow.
Known Issues
The ticket system lists all known outstanding issues with the Spree core. Some issues have a release target (milestone) attached: this is an indication of how soon an issue will be tackled.
There are some problems which we have traced to other projects. We list a few significant ones here.
Ruby 1.9 and Sqlite3
This combination doesn’t work with Rails 2.3.5: the change_column
calls make all fields into NOT NULL
.
See the related
ticket
for more info.
Workaround: apply the Rails patch by hand, or use MySQL instead if you want to try Ruby1.9