Saturday, 29 March 2014

Rails Templates

We've all been there, the start of a new shiny project, we hit rails new and, well, we follow the same motions we do every time we create a new Rails app.

We install devise, or maybe minitest, then follow it up with shoulda matchers, bootstrap and more. We have our little preferred starting stack, but we waste hours reimplementing it in every new project that comes our way.

Rails gives us the capacity to create our own templates which will dictate our starting stack as well as enable us to get some of the tedious after bundle setups out the way. To start with, create a template file templater.rb

Once we have that out the way let's go and automate adding some gems to our gemfile, now we can do this in a few different ways, the first being:

gem "mysql"
# We can also give it the usual gem options like so:
gem "technoweenie-restful-authentication", :lib => "restful-authentication", :source => ""
gem "rails", "3.0", :git => "git://"

Another option is to plug your gems into a group:

gem_group :development, :test do
  gem "rspec-rails"

Finally we can start leveraging Thor to install our gems like so:

inside app_name do
  run 'bundle install'

Once our gems are installed the next steps in setting up our application usually involve a bunch of generators, no worries, we can handle this as well

generate 'devise:install'

generate 'cancan:ability'
We can also do some really nice things around file manipulation, for instance we use the bootstrap-sass gem and need to add to our application.css.scss the bootstrap requirements.
append_file 'app/assets/stylesheets/application.css.scss' , <<-EOF
 @import "bootstrap";
 @import "bootstrap/theme";

Because the rails template api utilises Thor it means we have access to all of the usual suspects like remove_file, copy_file, but also really useful methods like inject_into_file

inject_into_file 'app/assets/javascripts/application.js', "\n//= require bootstrap\n", after: "//= require jquery_ujs"

This gives us the capacity to inject specific content within our files using only a regex match which is really useful especially for gems that will require adjustments to our spec_helper.rb file like the devise test helpers for instance.

We can also add some logic to our templates by using either the yes? method like so:

generate 'devise:views' if yes?("Generate Devise Views?")

Which will prompt the user to make a decision on whether or not we want to generate devise views for this particular project.

Additionally we can use the ask method to add some more complex logic to perhaps determine the extra individual capistrano environments we want to create:

environments = ask("What environments do you want in addition to production?, please separate with commas")

environments = environments.split(",")

environments.each do |env|
  create_file "config/deploy/#{env}.rb"

All these methods really mean we can not only have a well maintained template file all ready to use but really automate our entire new application process.

You can use a template to keep and maintain template files, eg: overriding the default view generators and replace them with haml templates. However, this does mean that you will no longer be able to use the one file for the template, which reduces your ability to be able to just call it from your github repo. It is possible in some cases to just use a string to store the file contents and create the file with them this way, but this has issues with maintainability over the long term.

Rails templates are a very easy way to minimise your ramp up time during the initial stages of a project, particularly if you are using the same stack over and over again.

Tuesday, 25 March 2014

(Microsoft) Access all areas

Over our short life as a company, we have worked with 3 clients who wanted to move from their existing Microsoft Access system to a more modern solution.  There appears to be a pattern forming where:

  • The current system has be band aided for too long (often breaking)
  • The company has grown beyond the original scope of the system
  • The fidelity of the data is questionable
  • Increased administration overhead of maintaining the data / reports required
  • Extending the system to clients and partners is required
  • A more User Centred Design (UCD) is desired
  • and of course, it needed to be web based.

When looking at migrating a system, it isn’t just a matter of creating like for like functionality. Note that our first project of this kind stipulated that this was mostly the case, and it took some convincing to extend the brief.

So how do we pop the Microsoft Access db in one end and out pops the rails system out the other?

Some of the activities that we undertake are:

  • Determine the current pain points of the system
  • Determine the desired features not currently available
  • Look at the existing forms, external to the system that are being used 
  • Look at existing database schemas
  • Develop scenarios and use cases fro the new system
  • Develop the ETL process for the data

Over the course of these projects, we have developed tools and processes to assist with the migration of Microsoft Access systems, and we are ready for the next one!

I can recall back 20 or so years wrestling with Northwind sample Microsoft Access databases, before embarking on that chapter of my development journey, not realising that 2 decades on, I would be revisiting.  I wonder if in 2034 I will be recalling my cancan gem experiences?