Deploy Spree 1.0 on Heroku

I am in the process of moving my digital house to the new Octopress-based ruby-journal.com, there are many things to clean up and migrate but I guess for now I will do double-post on this site and the new site.

Please head to http://ruby-journal.com/spree-1-0-stable-deployment-on-heroku/ if you want to read my tutorial on how to deploy Spree 1.0 on Heroku

How to create new Report extension in Spree 0.70.x

In this tutorial, I will show how to create new Report as extension for Spree 0.70.x backend from scratch. The idea is to generate a new extension with our new Report logic and register it by having the function to be merged with the constant AVAILABLE_REPORTS of the Admin::ReportsController. No rocket-science here, it’s pure basic RoR coding, and I hope I could show you a thing or two onto how to write your own extension for Spree.

Prerequisites

It is required that Spree 0.70.x is installed on your computer.

$ gem install spree --version=0.70.2

Generate new extension

Thanks to Spree generator, we could generate a new extension for Spree easily by using spree command. Let’s create our cool FooReport:

$ spree extension FooReport

Spree generates a skeleton mountable engine with name ‘spree_foo_report’:

      create  spree_foo_report
      create  spree_foo_report/app
      create  spree_foo_report/app/assets/javascripts/admin/spree_foo_report.js
      create  spree_foo_report/app/assets/javascripts/store/spree_foo_report.js
      create  spree_foo_report/app/assets/stylesheets/admin/spree_foo_report.css
      create  spree_foo_report/app/assets/stylesheets/store/spree_foo_report.css
      create  spree_foo_report/app/controllers
      create  spree_foo_report/app/helpers
      create  spree_foo_report/app/models
      create  spree_foo_report/app/views
      create  spree_foo_report/app/overrides
      create  spree_foo_report/config
      create  spree_foo_report/db
      create  spree_foo_report/lib
      create  spree_foo_report/lib/spree_foo_report.rb
      create  spree_foo_report/lib/spree_foo_report/engine.rb
      create  spree_foo_report/lib/generators/spree_foo_report/install/install_generator.rb
      create  spree_foo_report/script
      create  spree_foo_report/script/rails
      create  spree_foo_report/spec
      create  spree_foo_report/LICENSE
      create  spree_foo_report/Rakefile
      create  spree_foo_report/README.md
      create  spree_foo_report/.gitignore
      create  spree_foo_report/spree_foo_report.gemspec
      create  spree_foo_report/Versionfile
      create  spree_foo_report/config/routes.rb
      create  spree_foo_report/spec/spec_helper.rb
      create  spree_foo_report/.rspec
      append  Gemfile

Customize extension

gemspec

Thanks to greatness of mountable engine brought by Rails 3.1, now we could have our Spree extension deployed as gem and easily distributed with everyone. We need to provide details for our gem. Change the file spree_foo_report.gemspec:

# encoding: UTF-8
Gem::Specification.new do |s|
  s.platform    = Gem::Platform::RUBY
  s.name        = 'spree_foo_report'
  s.version     = '0.1'
  s.summary     = 'The Foo Man Chew Report'
  s.description = 'All the secret of Universe'
  s.required_ruby_version = '>= 1.8.7'

  s.author            = 'Foo Man Chew'
  s.email             = 'foo@man-chew.com'
  s.homepage          = 'http://github.com/foo-man-chew/spree_foo_report'

  s.files         = `git ls-files`.split("\n")
  s.test_files    = `git ls-files -- {test,spec,features}/*`.split("\n")
  s.require_path = 'lib'
  s.requirements << 'none'

  s.add_dependency 'spree_core', '>= 0.70.2'
  s.add_development_dependency 'rspec-rails'
end

If you are writing a public extension, the best practice is to have your GitHub URL as the homepage.

Versionfile

In the scope of this tutorial, our extension is written for Spree 0.70.x. However if future version is released which might break our current codebase, we could easily separate our code into Git branches or taggings. So Versionfile comes in handy, it designate the compatibility with different version of Spree . Read more at http://spreecommerce.com/documentation/extensions.html#versionfile. Change our Versionfile to:

# This file is used to designate compatibility with different versions of Spree
# Please see http://spreecommerce.com/documentation/extensions.html#versionfile for details

"0.70.x" => { :branch => "0-70-stable"}

README

README.mdfile is used to describe your extension. Now we add some installation and testing details:

Spree Foo Report
================

Fooo foo fooo fooo .. M..AN..CHEW!!!

Installation
------------

Append to your Gemfile:

    gem 'spree_foo_report', :git => 'git://github.com/foo-man-chew/spree_foo_report.git'

Testing
-------

Be sure to add the rspec-rails gem to your Gemfile and then create a dummy test app for the specs to run against.

    $ bundle exec rake test app
    $ bundle exec rspec spec

Copyright (c) 2011 Foo Man Chew, released under the New BSD License

ReportsController Decorator

We extends the Spree Core ReportsController by adding a new file in app/controllers/admin/reports_controller_decorator.rb:

Admin::ReportsController.class_eval do
  AVAILABLE_REPORTS.merge({:foo_report => {:name => I18n.t(:foo_name), :description => I18n.t(:foo_description)}})

  def foo_report
    # Add your logic here
  end
end

By having our new foo_report added in AVAILABLE_REPORTS, this ensure our new report to be listed on admin/reports index page. Yet, we are not done, we need to add in translation string for foo_name and foo_description by adding those 2 into config/locales/en.yml:

---
en:
  foo_name: The Foo Report
  foo_description: The You Know All Report

View

But what’s good for a report with no visual presentation? Let’s add in our View at app/views/admin/reports/foo_report.html.erb. Please note that the view name should be the same as the function name.

<h1>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</h1>

Routing

We’re nearly there, the last thing is to configure the routing. Edit config/routes.rb:

Rails.application.routes.draw do
  match '/admin/reports/foo_report' => 'admin/reports#foo_report', :via => [:get, :post]
end

Testing

There are 2 ways to try out our work, first is to build our gem and have it included in sandbox’s Gemfile OR we could commit the whole extension to GH and configure our Gemfile to use git path.

Howto enforce SSL on all front-end pages in Spree 0.11.x

In Spree production mode, SSL mode is activated if running with /admin (backend) but it’s not activated on front-end pages (non /admin). So how to enforce SSL on every frontend pages? Easy, simply extend Spree:BaseController like this in your SiteExtension:

class SiteExtension < Spree::Extension
  def activate
    Spree::BaseController.class_eval do
      protected
      def ssl_required?
        ssl_supported?
      end
    end
  end
end