Upgrading Modules to 3.4.x

peakpg edited this page May 30, 2012 · 15 revisions
Clone this wiki locally

BrowserCMS 3.4.x will be compatible with Rails 3.1.x. In order to use existing modules with this version of browsercms, they also need to be upgraded to work against browsercms 3.4.x (and rails 3.1). To help simplify this process, we have updatedthe command line tool in the BrowserCMS gem, called bcms-upgrade. This tool can be run on an existing BrowserCMS 3.3.x module to upgrade it.

In addition, its very likely that these instructions will also work when upgrading to Rails 3.2.x/BrowserCMS 3.5.x.

A. What Changed in 3.4.x?

Here's the changes for 3.4.x that will affect modules.

  • Asset Pipeline - Modules can now include their JS/HTML/CSS/Images via the Asset pipeline, which allows for improved code organization.
  • Namespaced Classes - Nearly all the Core CMS classes are now namespaced under Cms::, which should allow BrowserCMS (and modules) to be added to other projects without namespacing conflicts.
  • Standardized Version Column - In <= 3.3.x, each versioned block has its own versions table, which maintained a pointer to the 'current' row by a named column. So in html_block_versions, it had a html_block_id column. With how Rails treats namespaced models, this got too messy, so ALL Block Versions just use the column original_record_id. This means, for any modules, you need to update your _versions table accordingly.

B. How to Upgrade

First things first: Check in your module code. Upgrading a module is going to delete and alter a large number of files. This upgrade script assumes that the project is managed in Git, and will use Git to revert some files during the script.

Here's what you need to do inside your project's directory

$ gem install browsercms
$ bcms-upgrade module

This will modify a whole bunch of files. From there, you will need to make some further tweaks, depending on how your module works.

C. Next Steps

The examples below assume a module called 'bcms_petstore' wherever paths are used.

1. Configuring Routing

Move any Engine routes from lib/bcms_petstore/routes.rb -> config/routes. Assume you have the following file:

# In lib/bcms_petstore/routes.rb
module Cms::Routes
  def routes_for_bcms_petstore
    namespace(:cms) do 
      content_blocks :pet_food
    end  
  end
end

Modify config/routes.rb to look like this, then delete lib/bcms_petstore/routes.rb.

BcmsPetstore::Engine.routes.draw do
   content_blocks :pet_food  
end

Not that you do not need to namespace under :cms anymore (Isolated engines automatically are namespaced under the engine name).

2. Update the Gemspec

Review the gemspec and make sure it has:

  • Correct dependencies (i.e. browsercms ~> 3.4.0)
  • Packages the right files

3. Namespace classes

Any references to core BrowserCMS classes need to have a Cms:: added to them. This will mostly likely show up in seed data/migrations, or in portlets/controllers. Hopefully your unit/integration tests will catch theses. For example, before:

ContentType.create!(:name => "Widgets", :group_name => "Widget")

widget_page = Page.create!(
  :name => "Widget", 
  :path => "/widget", 
  :section => Section.root.first,
  :template_file_name => "default.html.erb")

After:

Cms::ContentType.create!(:name => "Widgets", :group_name => "Widget")

widget_page = Cms::Page.create!(
  :name => "Widget", 
  :path => "/widget", 
  :section => Cms::Section.root.first,
  :template_file_name => "default.html.erb")

You will also need to move all your Engines controllers/class under the Engine namespace. So for example,

# Before: app/controllers/cms/widgets_controller.rb
class Cms::WidgetsController < Cms::ContentBlockController
end

# After: app/controllers/bcms_your_module/widgets_controller.rb
module BcmsYourModule
  class WidgetsController < Cms::ContentBlockController
  end
end

Ensure the Engine has an isolated namespace, like so:

# In lib/bcms_widgets/engine.rb
require 'browsercms'
module BcmsWidgets
  class Engine < Rails::Engine
    isolate_namespace BcmsWidgets
    include Cms::Module
  end
end

4. Database/Migrations

You will need to make some changes to your migrations before rake and generators will work. Eventually, you will want to run the following tasks, but until rake -T stops throwing errors you will need to keep debugging the issues.

$ cd test/dummy 
$ bundle exec rake railties:install:migrations # Will add BrowserCMS migrations to your test/dummy project
$ rails g browser_cms:cms # Add seed data to the test/dummy project
$ bundle exec rake db:install # In root of project, you need to run `rake app:db:install`

You may need to reorder the timestamps of your engine's migrations so they come after BrowserCMS ones. The exact timestamps don't matter anymore, as rake railties:install:migrations will generate new relative timestamps when adding migrations to a project.

Add a migration to rename the table to start with the name of your module, i.e.: bcms_your_module_

# For CMS 3.5.x
require 'cms/upgrades/v3_5_0'
def change
    v3_5_0_apply_namespace_to_block("BcmsYourModule", "Widget")
end

# For CMS 3.4.x
def change
    rename_table :widgets, :bcms_your_module_widgets 
    rename_table :widget_versions, :bcms_your_module_widget_versions 
    if column_exists? :bcms_your_module_widget_versions, :widget_id
      rename_column :bcms_your_module_widget_versions, :widget_id, :original_record_id
    end
end

In your Installation generator, you can add the following to have it copy all your project migrations as part of the installation.

def copy_migrations
   rake 'bcms_your_module:install:migrations'
end

4. Test installing the gem

When you are done with all your changes, be sure to package and test the gem locally on a BrowserCMS project, using the following steps:

$ rake install
$ cd /path/to/projects
$ bcms new test_project
$ cd test_project
$ rails g cms:install bcms_your_module
$ rake db:install

Then boot the server, and verify your module works. You may need to edit the .gemspec to make sure things work correctly. Also, review the Install Generator and make sure it's doing everything it needs to (including mounting the engine if needed), like so:

def add_routes
  mount_engine(BcmsYourModule)
end

Short version

See [https://gist.github.com/2776664] for a very abbreviated version of these commands.

Help! Something's not working

Upgrades can be tricky things, so here is a potential set of things you might need encounter while upgrading to make things work.