Alisdair McDiarmid has a great write up on solving the problems of serialising and deserializing custom objects to yaml in rails whilst in development and getting around the ArgumentError: undefined class/module UnknownClass error that are thrown due to classes not being loaded.

The solution is to eager load classes and reload them each request to make sure that when YAML deserialization occurs the classes are present as usually this process doesnt trigger the default lazy loading of classes in development.

The solution looks like thisSource
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Eager load all value objects, as they may be instantiated from
# YAML before the symbol is referenced
config.before_initialize do |app|
    app.config.paths.add 'app/values', :eager_load => true
end

# Reload cached/serialized classes before every request (in development
# mode) or on startup (in production mode)
config.to_prepare do
    Dir[ File.expand_path(Rails.root.join("app/values/*.rb")) ].each do |file|
        require_dependency file
    end
    require_dependency 'article_cache'
end

Testing, SimpleCov and Missed Coverage

This solution was great, it solves the loading issue but during development I noticed the lines of code covered by SimpleCov was reduced, looking into know issues on the SimpleCov github one explained the reason why files where missing. The above solution of preloading the classes for deserialization means that the files are already loaded in memory before SimpleCov initialises and thus cant be tracked by Ruby’s built in coverage mechanism.

Solution

As of rails 3.1, objects can be serialised to JSON as well as YAML. While it requires the addition of two methods to the class in question it does mean the class doesn’t need to be preloaded and thus allows the code coverage to be tracked.

Adding the following two methods in your class and the additional JSON option to serialize in the model file allows for objects to be reinitialised based on the stored data parameters saved as JSON in the database.

in the model file
1
serialize :column_name, JSON
Serializing and Deserializing with JSONsource
1
2
3
4
5
6
7
def self.json_create(o)
  new(*o['data'])
end

def to_json(*a)
  { 'json_class' => self.class.name, 'data' => [id, name, next_step] }.to_json(*a)
end

One of my recent tasks has been to build a preview of a form submission into an existing application. Having done something similar in the past involving changing the forms action with javascript, ajax posting the form (including images), generating a preview, changing the form back blaa blaa blaa blaa blaaaaa. I wanted to find a cleaner way to a) deal with the preview and b) ajaxing blob data (image/files) and thanks to not having to support IE implemented the following procedure using FormData and XMLHttpRequest 2.

Read on →

Setup Chef and Creating a EC2 instance

Chef is a fantastic tool for automating the process bootstrapping a fresh server so that once you have got it running how you want, replicating that configuration and setup requires very little effort what so ever.

Chef has two different use cases, Chef server (wether that be hosted or private) or Chef Solo. Chef solo allows you to interact directly with the machine your wanting to administrate and is very useful for bootstrapping a vagrant image for instance. Chef Server offers a centralised place for you to push your configurations and recipes so that when working with multiple servers (known as nodes or chef clients) you don’t have to update each one individually as each client can be set to poll to server for any updates.

For my first time using chef i through myself straight in at the deep end in that i wanted to put together a full working EC2 instance that would run my usual heroku stack (nginx, unicorn, ruby, rails and postgres). I opted for using Opscodes free Chef hosted plan for my Chef server and got straight to it.

Read on →

Gemfile

Install the following gems with bundle install

Gemfile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
.....
group :test_envs do
  gem 'rspec-rails', "~> 2.0"
  gem 'factory_girl_rails'
  gem 'faker'
  gem 'capybara', "~> 2.0.2"
  gem 'database_cleaner', "~> 0.9.1"
  gem 'launchy'

  # file system event triggers for ruby. See note at end about RVM 
  gem 'rb-fsevent', '0.9.3'

  # Notifications of test states, Requires Growl and growlnotify to be installed
  gem 'growl', '1.0.3'

  # Automated test running and speed imporvements
  gem 'guard-rspec'
  gem 'guard-spork', '1.2.0'
  gem 'childprocess', '0.3.6'# this was due to errors appearing in 0.3.7 and higher
  gem 'spork', '0.9.2'
  gem 'debugger'
end
.....

spec/spec_helper

Read on →

To get the tolk gem to work along side the Strong Parameters gem we need to apply a monkey patch to tolk

config/initalizers/tolk.rb
1
2
3
4
5
6
Tolk::LocalesController.class_eval do
    def create
      Tolk::Locale.create!(params[:tolk_locale].try(:permit!))
      redirect_to :action => :index
    end
end

As to not forget the process of packaging up a gem and putting it on my own hosting just follow these simple tests :–

Read on →