Railsmagazine60x60 Converting A Rails Site to Refinery CMS

by Christopher W. Lehman

Issue: Vol 2, Issue 2 - Field Day

published in October 2010

Chriswlehman crop

Chris Lehman has been a semiconductor industry IT Manager and Software Developer for over twenty years at companies such as IBM, Cypress Semiconductor and Ford Microelectronics. He has watched the industry grow from DEC mainframes to Sun SPARC platforms to Open Source Linux on desktops, with a lot of Microsoft products in between. He is currently Technical Systems Manager at Boomerang Lending, where he drives web site development, the integration of the Ruby on Rails framework with Rich Internet Applications and general IT management.

Chris holds a Doctor of Computer Science degree from Colorado Technical University (Colorado Springs, Colorado) and a Bachelors degree in Electrical Engineering from Northeastern University (Boston, Massachusetts). His current professional interests include Agile and Scrum project management, LAN/WAN infrastructure security, virtualization technologies, cloud computing and creating web sites with Ruby on Rails.

Introduction

Every e-commerce business must nail down three key business issues: Trust, Reputation and Brand Name Recognition. Trust and Reputation require time and professional integrity – your organization either has it or it doesn't, and that's largely out of your control. Brand Name Recognition can be managed through advertising, Public Relations campaigns, media coverage and through Search Engine Optimization (SEO) and Pay Per Click campaigns, to name just a few of the available strategies.

Although SEO is part science and part sorcery, we do know that new content on your web site, updated often, can significantly improve your site's search engine rankings. Adding a new content page or a new landing page is pretty easy in Rails, but do you really want your Marketing Department to be doing that? I didn't think so. But that means that the Development Team (that's you) is in the critical path for content creation, which can be a serious issue if your SEO person is on the ball and needs ten new pages deployed this week, and by the way, I need six of them deployed tomorrow to coincide with the launch of our new Press Release. Not a good situation. What you need is a Content Management System – a safe, independent way of letting your CEO and Marketing crew add content to your site at will, without impacting your development schedules. We looked at various CMS implementations, and Refinery jumped out pretty quickly since it was a Rails-based architecture and had a clean way of adding SEO-aware pages to the site.

Going with Refinery was a good decision for us, and the conversion of our web site is almost complete, so we would like to share some of the discoveries that we made during the conversion process.

Create a good set of tests before you begin the conversion

You'll sleep better with a known good set of tests (at least unit and functional) for your current web site before you begin the conversion. The tests should migrate over to Refinery without too many modifications (if any), assuming you don't change the names of your controllers, models and views. The Refinery folks seem to be using Cucumber, which is a good choice, and which is where we want to be eventually as well. For now, we're using the Test::Unit basics, with fixtures.

Customizing authentication can be complex and time consuming

Refinery has a built-in authentication plugin, which takes its foundation from Ben Johnson's Authlogic gem. This is a great authentication tool, and it's well-documented, but it can be complex, as there is a lot of session magic going on beneath the surface. The authentication plugin is tightly coupled to the admin backend of Refinery. If you will also need non-admin user authentication for customers or other people external to your organization, you will need to move the user and session controllers and models into the main app area and modify the code from there. Take a look at naumav's refinery_with_users fork on github as one example. Give yourself some extra time to get this right, especially if you have not used Authlogic before. If you have a multi-person development team, you may want to designate someone to be the local authentication guru.

Emulate your production web server environment in your development environment

The WEBrick server that comes with Rails is very convenient, but you need to reproduce your production web server environment in your development environment within the first couple of weeks of the conversion process. I found some subtle behavioral differences between WEBrick and Apache / Passenger that would surface as I pushed development code out to the production server; using the same server configuration in both locations kept the surprises to a minimum.

Determine which models will be converted to plugins, and which can be left alone

Not every model needs to be a plugin. For example, our Notifier model, an extension of the ActionMailer class, does not need any admin backend support, so we kept it in the main app area of the site.

Models with associations should be grouped as all plugins or as all non-plugins

Consider the models you may have for a mortgage company: users, loan applications and mortgage contracts. The associations between the models may look something like:

user :has_many loan_applications

user :has_one mortgage

mortgage :belongs_to loan_application

loan_application :belongs_to user

We found that it was cleaner to convert all models with associations to Refinery plugins rather than scatter them between the main app directory and the plugins directory, even if a model did not necessarily need admin support from the backend. If none of your associated models require admin functionality, then you can consider leaving them under the main app folder as you normally would with a non-Refinery Rails framework.

Use the power of themes

An intelligent use of themes will allow your design and graphics teams to try various CSS styles during development. Remember the Rails “Convention Over Configuration” mantra - try to use the built-in page design elements that Refinery already knows about. This still gives you a lot of flexibility, but sticking with the built-in one or two column layouts in the /pages hierarchy can keep the design portion of the development cycle on schedule. Themes can also make it possible to quickly spin off a clone of your current web site. For example, given a mythical web site called www.buy-a-car-in-colorado.biz, you decide to start marketing your services in Nevada. You could pull a new git copy of the current site, develop a completely new theme and use your favorite IDE to replace all references to Colorado with Nevada. Your backend admin functionality is already in place, your models and controllers are already working, so create your new databases, configure a web server, and www.buy-a-car-in-nevada.biz is almost ready to go. You'll probably be waiting for the design and graphics folks to catch up with you, which is a great position to be in.

The built in editor can be quirky

The WYMeditor is widely used by a number of different open source and proprietary applications, including Drupal, Django and WordPress. We found it to be hard to use when doing cut and paste operations from other editors. The HTML mode seems to have a mind of its own, particularly when using table tags; the positioning of table data would sometimes change after an edit / save operation. The best approach for us was to create the initial content in external editor, and paste it into WYMeditor, and then do subsequent edits from there. If your content will be relatively simple, you will probably not notice anything amiss. Your non-HTML-aware content providers may need a WYMeditor jump start.

Caching in development mode can be problematic

With RAILS_ENV set to “development”, your entire code base is constantly being loaded. This is very convenient, but we would experience strange program crashes on occasion. This is not a total surprise, given that the Refinery architecture consists of a significant amount of class inheritance and module loading. You may need to set config.cache_classes = true in config/environments/development.rb, and you may also need to activate the config.after_initialize block in the same file. If you make these modifications, be sure to restart your web server when testing new changes.

Conclusion

Our new web site, www.boomeranglending.com will launch on or before September 1st. It took about 6 weeks for one developer (me) to go through the Refinery learning curve and port the code and database to the new site. Web design and graphics (new logo, branding, messaging, etc) was outsourced and was not included in the development schedule. Our SEO and Marketing tactics will be greatly enhanced with the addition of Refinery's “No Developer Required” page content generation system.