Ruby on Rails with Dan Watson


Programming in Ruby tutorials and examples

ActiveRecord - Simple Key Value Store

Over the last few weeks I have been playing with the idea of having a simple database backed key value store using Rails ActiveRecord. The ActiveRecord class should act like a singleton where arbitrary keys can be set with a value of any type (simple values, hashes, arrays or complex objects). I have come up with the idea of using method missing to set and retrieve the key / value pair where the value’s are saved as yaml and then cast back to the correct type when retrieved.

class Application < ActiveRecord::Base
  set_table_name "application_settings"
  
  def self.method_missing(method, *args, &block)
    return self.send method, *args, &block if self.respond_to? method
    method_name = method.to_s
    if method_name =~ /=/
      return self.set method_name.gsub("=", ""), args.first
    else
      return self.get method_name
    end
  end
  
  private 
  def self.get setting
    entry = Application.where(:key => setting).first
    entry.nil? ? nil : YAML.load(entry.value)
  end
  
  def self.set key, value
    setting = Application.where(:key => key).first || Application.new(:key => key)
    setting.update_attribute(:value, value.to_yaml)
  end
end

Below is the migration needed to setup the database table for your application settings class.

class CreateApplicationSettings < ActiveRecord::Migration
  def up
    create_table :application_settings, :id => false do |t|
      t.string :key
      t.text :value

      t.timestamps
    end
    add_index :application_settings, :key, :unique => true
  end
  
  def down
    drop_table :application_settings
  end
end

Using the class it is possible to set a value to any arbitrary key by calling the setting name setter method just like it is a defined class attribute.

Application.some_arbitrary_setting = 12903
Application.my_hash_foo = { :foo => "bar" }

To retrieve the setting make a method call to the key name as if it were a defined class attribute.

Application.some_arbitrary_setting
=> 12903 

Application.my_hash_foo 
=> {:foo=>"bar"}

MiniRecord and Timestamps

Yesterday I have had a patch accepted into the main branch of MiniRecord which allows for easier syntax when adding timestamps to your ActiveRecord models. Before you would have had to place the following code into each of your model classes to have the correct created_at and updated_at columns in your database.

class Person < ActiveRecord::Base
         col :created_at, :updated_at, :as => :datetime
end

This is now is able to be implemented by just calling on the timestamps class method.

class Person < ActiveRecord::Base
  timestamps
end

This feature is only currently available from the main repository so if you would like to use it just add the following line to your Gemfile.

gem 'mini_record', :git => 'git://github.com/DAddYE/mini_record.git'

Migrate All of Your Model Classes When Using MiniRecord

MiniRecord is a micro extension for ActiveRecord which allows you to define your schema directly in your model in a similar way to others projects like DataMapper or MongoMapper.

class Post < ActiveRecord::Base   col :title   col :description, :as => :text
  col :permalink, :index => true, :limit => 50
  col :comments_count, :as => :integer
  col :category, :as => :references, :index => true
end

Once the columns are defined inside the model you call the auto_upgrade! class method to run the migration on a class by class basis.

Post.auto_upgrade!

Most (if not all) projects have multiple model classes, and it is common to make changes to more than one model at a time. When using standard rails migrations you have access to the rake db:migrate task to migrate all the changes made to the schema. Unfortunately out of the box the MiniRecord gem does not provide this. Introducing rake mini_record:migrate. Add this rake task to your Rails project and when called it will loop over all of your model classes auto upgrading (migrating) them one by one.

if defined?(Rails) && (Rails.env == 'development')
    Rails.logger = Logger.new(STDOUT)
end

namespace :mini_record do
      desc "Auto migration of database"
          task :migrate => :environment do
              Dir["app/models/*.rb"].each do |file_path|
              basename = File.basename(file_path, File.extname(file_path))
              clazz = basename.camelize.constantize
              clazz.auto_upgrade! if clazz.ancestors.include?(ActiveRecord::Base)
          end
      end
end

Convert Dates Between Ruby and Javascript

This is a quick overview on how to convert dates between Ruby and Javascript.

Firstly lets tackle the Ruby to Javascript conversion.

Your Ruby Time object needs to be converted into a timestamp which can be done by calling the to_i method. This gives you the integer representation of the full date and time.

  Ruby: Time.now.to_i

Once your Javascript code has access to the timestamp it can be converted to a Javascript date object by passing the integer representation of the Ruby time object to Javascripts date constructor and then multiplying it by 1000.

  Javascript: new Date(timestamp * 1000)

It is also possible to convert Javascript date objects back to Ruby time objects.

By placing the plus operator in front of the Javascript date object it coerces it into number which then needs to be divided by 1000. This gives you the timestamp representation of the Javascript date object

  Javascript: +new Date() / 1000

Your javascript timestamp can then be converted back to a Ruby time object by passing the timestamp (integer) to the Time.at method.

  Ruby: Time.at(your_javascript_timestamp)

All in all this is the simplest and most reliable way I have found to do send dates back and forwards between between both languages.

Large Ruby File Downloads Done Right!

I have recently been writing a utility in ruby to move some very large files across from Rackspace’s Cloud to Amazon S3. Basically the utility firstly downloads a file from Rackspace and then uploads it to S3. Well this all seems very straight forwards but there are considerations that have to be made when you download large files using any scripted utility.

Some of the file’s that are being downloaded are 1GB or more in size and I am using an Amazon Micro EC2 server that only has 613 mg of RAM. Due to the available RAM usually being smaller than the file size of the download the last thing I want to do is to put the http response stream into memory before writing it out to disk. This would cause all kinds of fail. Basically the server will run out of memory and kill the download process before it is complete. What is needed is to download and stream the file directly to disk leaving the RAM well alone.

Below is code I have extracted from my utility and simplified.

Net::HTTP.start("someurl_without_the_protocol.com") do |http|
  begin
    file = open("/path/to/file.mov", 'wb')
    http.request_get('/' + URI.encode("file.mov")) do |response|
      response.read_body do |segment|
        file.write(segment)
      end
    end
  ensure
    file.close
  end
end

Replace the Rails Console With Pry

If like me you prefer to use Pry over IRB you probably want your rails app to start Pry with your rails environment loaded instead of IRB when running the rails console.

Luckily it’s really easy to do. Just open up config/environments/development.rb and add the following code.

MyApp::Application.configure do
    silence_warnings do
        begin
            require 'pry'
            IRB = Pry
        rescue LoadError
        end
    end
end

Simples!

Jacob’s Battle With Cancer Update

Jacob finished chemotherapy this past Sunday and I cannot express how relieved we all are. It has been one year since he started his treatment and he has had a total of fourteen chemotherapy sessions. Each session was administered over three days every three week’s. Jacob did have a small break from chemotherapy in December so he was well enough to undergo surgery to remove his tumor.

Jacob, Gemma and I have been in Jacksonville Florida for the past five week’s whilst Jacob has undergone proton radiation therapy at the University of Florida Proton Institute (UFPI). As of today Jacob has successfully completed twelve of twenty eight radiations.

Now we are settled into the routine of daily anesthetics, radiation and are acclimatized to our new surroundings, I have found the time to write a little about what exactly we have come out here to do and why we are doing it.

Proton radiotherapy works on the same principle as conventional (photon) radiotherapy, administer radiation to the area containing cancerous cells in order to damage the cells DNA so they die and are unable to multiply. The problem with photon particles is that they travel through the affected area of the body and do not stop, so they not only disrupt the ‘bad’ cells but also the normal cells in the surrounding structures. As Jacob’s tumor was in his skull this type of radiation would have destroyed much of Jacob’s brain and would have left him with a very poor quality of life or possibly even no life.

Proton radiation is different in that when the radiation is administered the proton particles stop once they reach a specified depth. By doing this there is much less ‘over spill’ (for lack of better words) of radiation to the surrounding structures. This will leave Jacob with a much better quality of life whilst still disrupting any cancer cells left over from excision of his tumor.

Unfortunately even though this sound’s like a miracle cure it does have its side affects. Even though the radiation is more controlled there will be some damage to normal cells within the brain. We have been told by the radiologist at UFPI to expect some deafness in Jacob’s right ear and a loss of field vision in his left eye. Also there is the possibility that he will have difficulties during his education but it is unknown to what extent. All these symptom’s may or may not occur and could present themselves a month after treatment or even forty or fifty years later!

Jacob has coped tremendously well with the radiation which is administered Monday to Friday under general anesthetic. He has remained the positive, determined and happy little boy he always has been and has even learnt to walk and sing during this trip. Over the coming months Jacob should start to feel even better without the hardship of undergoing chemotherapy (we will even find out if he is going to have ginger hair like he had in December during the break from chemo!).

Just wanted to write a thank you to all of you that supported us. The money you helped us raise to come out here to Florida has been a great help and has enabled Jacob to be comfortable and well cared for. Without your donation’s this trip would be much more demanding on Jacob, Gemma and myself. Thank you all.

Book Review - Eloquent Ruby

A few month’s ago I read Design Patterns In Ruby by Russ Olsen which is one of the best software engineering books I have read. I didn’t think Russ could top himself with his next book Eloquent Ruby but he has!

About five years ago when I started writing Ruby I stumbled and bounced my way around different resources to learn the language. If only I could of had Eloquent Ruby way back when, then the whole process would have been a lot quicker and easier.

Eloquent Ruby is a one stop shop to learn everything from how you should structure your code all the way through to writing DSL’s. Russ takes each subject matter and splits them into small manageable sections of around 10 pages with a thorough explanation followed by pointers to real world implementations. I believe this is a great way to learn, theory plus application makes things stick (well at least in my mind).

So what is covered? Well basically everything you will need to know to write well rounded ruby code.

  • Write Code That Looks Like Ruby
  • Choose The Right Control Structure
  • Take Advantage Of Ruby’s Smart Collections
  • Take Advantage Of Ruby’s Smart Strings
  • Find The Right String With Regular Expressions
  • Use Symbols To Stand For Something
  • Treat Everything Like An Object - Because It Is
  • Embrace Dynamic Typing
  • Write Specs!
  • Construct Your Classes From Short, Focused Methods
  • Define Operators Respectfully
  • Create Classes That Understand Equality
  • Get The Behavior You Need With Singleton And Class Methods
  • Use Class Instance Variables
  • Use Modules As Name spaces
  • Use Modules As Mixins
  • Use Blocks To Iterate
  • Execute Around With A Block
  • Save Blocks To Execute Later
  • Use Hooks To Keep Your Program Informed
  • Use method_missing For Flexible Error Handling
  • Use method_missing For Delegation
  • Use method_missing To Build Flexible APIs
  • Update Existing Classes With Monkey Patching
  • Create Self Modifying Classes
  • Create Classes That Modify Their Subclasses
  • Invent Internal DSLs
  • Build External DSLs For Flexible Syntax
  • Package Your Programs As Gems
  • Know Your Ruby Implementation
  • Keep An Open Mind To Go With Those Open Classes

If you’re a novice programmer or season software engineer there will be something in this book for you so you better go and buy it.

Shout Mouth Blog Engine - V1.7 Released

I have just released Version 1.7 of the shout mouth blog engine. Shout mouth is a blog engine written using Ruby, Sinatra and DataMapper. It supports multiple authors, posts, tags, categories, comments and can be administered using any client that supports the metaweblog, movabletype, wordpress or blogger API’s. Checkout the read-me for further information. Any issues you can submit a pull request or contact me via dan at dotnetguy.co.uk

An Alternative to the XML-RPC Package From the Ruby Standard Library - Introducing Rapuncel

Over the last few months I have been writing a blog engine using sinatra, it’s called shout mouth. Shout mouth has a single xml-rpc endpoint which exposes the blogger, metaweblog, wordpress, movabletype and shout mouth specific xml-rpc methods.

The thing about shout mouth is there is no administration system only the exposed xml-rpc API’s to work with. I am happy using Windows Live Writer, Ecto and the Wordpress client for Android / iPhone to manage my blog but I know others will want to build a full-blown administration system.

I decided to write the shout mouth communicator gem to allow people to easily write their own administration systems (hint hint!). Shout mouth communicator is basically a wrapper around xml-rpc calls allowing administration of the shout mouth blog engine.

Initially I used the xml-rpc library from the RSL but I ran into two problems. Firstly when the response from shout mouth was large, like when you ask for all of your posts then the xml parser was not performant. Secondly it was choking parsing valid xml on large responses.

I was just about to start writing an xml-rpc client using nokogiri as the xml parser and I stumbled upon rapuncel. Rapuncel uses nokogiri under the covers to parse the xml-responses from the server. Basically this solved the performance issue when parsing large xml responses and also the xml parsing issue when REXML (the xml parser used by the RSL) was failing trying to parse valid xml.

So if you are going to be doing any work using xml-rpc and need to build a client then go and grab rapuncel.