How to Install ‘therubyracer’ or ‘libv8’ gem(s) on OSX

Recently, I need to move some Rails projects I was working on to new computer and this needs me to install all the dependencies for these projects.  While using bundler to install the gems; I encountered the following error:

extconf failed, exit code 1
Gem files will remain installed in /Users/ash/.rvm/gems/ruby-2.2.1/gems/libv8-3.16.14.3 for inspection.
Results logged to /Users/ash/.rvm/gems/ruby-2.2.1/extensions/x86_64-darwin-14/2.2.0-static/libv8-3.16.14.3/gem_make.out

An error occurred while installing libv8 (3.16.14.3), and Bundler cannot continue.
Make sure that `gem install libv8 -v '3.16.14.3'` succeeds before bundling.

Fortunately, with homebrew fixing this (on OSX 10.11, El Capitan at least) worked perfectly. Simply execute these commands:

brew install v8
gem install therubyracer
gem install libv8 -v '3.16.14.3' -- --with-system-v8

Estabilishing ActiveRecord Database Connections in Ruby (But Without Rails)

Anyone who has even the smallest amount of experience developing with Ruby on Rails knows that Rails has some pretty sweet configuration conventions which make switching between environments very easy. Switching from development to production to testing is as easy as changing the RAILS_ENV variable. No doubt Rails does some dark magic behind the scenes to trivialise this. But what if you’re writing an app in Ruby, without the Rails to guide you?

ActiveRecord 101

Establishing a database connection in ActiveRecord without Rails is pretty basic:

require 'active_record'

ActiveRecord::Base.establish_connection({
  adapter:  'sqlite3',
  database: 'db/test.sqlite3'
})

It establishes a connection to the specified database with the specified connection  configuration. If you were using MySQL or PostgreSQL you would provide the relevant configuration such as username, password and host. With the connection established, we can now start consuming the connection however we like. For example, we may want to use funky Rails’ style models (so we can easily create and populate tables and reference them):

ActiveRecord::Schema.define do
  create_table :things do |t|
    t.integer :id, :null => false
    t.string  :name
  end
end

class Thing < ActiveRecord::Base
end

Thing.create({
  id:   0,
  name: 'Broomstick'
})

Care about the Environment

The other magic in Rails is the environment selection. The main benefit with this is that we can have isolated connection configurations and have our Ruby app automatically select the correct settings for us (using our environment variable ENV).

require 'active_record'

conf = case ENV['DB']
when 'conf1'
{
  adapter: 'sqlite3',
  database: 'db/mydb1.sqlite3'
}
when 'conf2'
{
  adapter: 'sqlite3',
  database: 'db/mydb2.sqlite3'
}
else
  raise 'export DB=conf[n]'
end

ActiveRecord::Base.establish_connection conf

Mind you, before this will work you first need to set the environment variable:

export DB=conf1 # or conf2

Now, depending on ENV[‘DB’], the code will open a connection to the corresponding database.

Best Practises

It’s never a good idea to store sensitive information (like database connection information and usernames and password of any kind) in your code base. Rails uses an external database configuration file called database.yml to solve this problem, so lets implement one ourselves.

database.yml:

conf1:
  adapter: sqlite3
  database: db/mydb1.sqlite3

conf2:
  adapter: sqlite3
  database: db/mydb2.sqlite3

Loading this YAML file is very simple:

require 'active_record'
conf = YAML.load_file('database.yml')
ActiveRecord::Base.establish_connection conf[ENV['DB']]

Now we can set our environment variable same as before, but our code will look in a YAML file for the proper database configuration automatically, without having to store database connection information directly inside our code.

Association Cardinality in Rails

From time to time I’ve noticed people who struggle with cardinality and associations in Ruby on Rails. So, I thought I would attempt to create a cheat sheet here to help developers understand relationship cardinality and how it maps to associations.

ActiveRecord can be used to describe relations with one-to-one, one-to-many and many-to-many cardinality; where each model defines its relation to another. Let’s cover each of the three types of associations.

One-to-one

Use `has_one` in the base and `belongs_to` in the association:

class Family < ActiveRecord::Base
  has_one :home
end
class Home < ActiveRecord::Base
  belongs_to :family
end

A common question about a one-to-one association is ‘how to know which direction the has_one and belongs_to go?’  The correct way to know, is that whichever model has the foreign key, gets the `belongs_to`.  In this case, Home has the foreign key `family_id`.

One-to-one relationships are a bit odd, and as a general rule, if you find yourself using a lot of them, there is probably a better solution.

One-to-many

Use `has_many` in the base and `belongs_to` in the association:

class Family < ActiveRecord::Base
  has_many :parents
end
class Parent < ActiveRecord::Base
  belongs_to :family
end

This will be your most common relationship. As with one-to-one’s, the table with the foreign key gets the `belongs_to` (although this is a lot more obvious with a one-to-many). In this case the foreign key is `family_id`.

Many-to-many

These can be a lot more complicated and there is actually a couple of different ways to do it.

The first way involves a specific joining model. This results in 2 stages of has_many associations. It is referred to as `has_many :through` and is primarily used if you need to fully control the joining model/table:

class Family < ActiveRecord::Base
  belongs_to :parent
  belongs_to :kid
end
class Parent < ActiveRecord::Base
  has_many :kids, through: :families
end
class Kid < ActiveRecord::Base
  has_many :parents, through: :families
end

The second (and my preferred way) is to use the `has_and_belongs_to_many` method:

class Parent < ActiveRecord::Base
  has_and_belongs_to_many :kids 
end
class Kid < ActiveRecord::Base
  has_and_belongs_to_many :parents
end

The main difference (or disadvantage) with the `has_and_belongs_to_many`method is that the intermediary joining table and foreign keys need to be exactly named to match what Rails expects. Which many-to-many method you use ultimately depends on whether you need to work with the relationship model as its own entity directly.

MySQL utf8mb4 Encoding Breaks ActiveRecord’s Schema Setup

I recently wrote about the virtues of true UTF8 (utf8mb4) character sets in MySQL and how to change your database to use it. Today we will discuss a possible problem you may encounter when you do when programming on Ruby on Rails. The error looks something like this:

$ rake db:setup

Mysql::Error: Specified key was too long; max key length is 767 bytes:
CREATE UNIQUE INDEX unique_schema_migrations ON schema_migrations (version)

The problem exists because the utf8mb4 character set uses the full 4 bytes per character rather than the 1-3 of UTF8 (the character set most people mistakenly use thinking they’ll have full Unicode compliance). Because of this extra size, the schema_migration may no longer fit.

This small patch will set default mysql string column length to 191 instead of 255 which is the new index limit on utf8mb4 (aka real utf8).

# config/initializers/mysqlpls.rb
require 'active_record/connection_adapters/abstract_mysql_adapter'

module ActiveRecord
  module ConnectionAdapters
    class AbstractMysqlAdapter
      NATIVE_DATABASE_TYPES[:string] = { :name => "varchar", :limit => 191 }
    end
  end
end

 

Using Ruby’s Metaprogramming to Initialize an Object From a Hash

Consider the code:

class A
  attr_accessor :b, :c, :d, :e, :h, :i, :x
end

Now imagine that you want to initialize each instance variable to the one that has the same name in the hash.. Imagine all the repetitive and crappy code that would generate.

But this is Ruby and with Ruby there is *nearly* always a better way.  Instead, meta-program it, and mix-it-in.

module constructed_from_hash
 def initialize(h)
  h.each { |k, v| send("#{k}=", v) }
 end
end

class A
 include constructed_from_hash
 attr_accessor :b, :c, :d, :e, :h, :i, :x
end

Nice, elegant and clean. Just the way Ruby code is supposed to be. AND this code will now scale, as more accessors are added to the object over time, the constructor too, wont need reprogramming. If you don’t need to do this often, you can pull just the constructor out of the module and put it directly into the class, but this way provides the most flexibility.

Header image taken from Examining Dwemthy’s Array composite pattern. An interesting read in it’s own right. check it out.

How to Fix ‘Requirements installation failed’ When Installing RVM Ruby on OSX Mavericks

Installing Ruby with RVM on Mac is a cinch, simply execute:

\curl -sSL https://get.rvm.io | bash -s stable --ruby

But recently, while trying to install RVM instead of the default Mavericks Ruby, the script that normally just “works” fails with the ominous message:

: Requirements installation failed with status: 1.

It turns out to be something funky with Mavericks and the Homebrew step of the installation. Luckily, despite the failure of the script, you can simply install Hombrew manually to solve the problem. Installing Homebrew is a triviality, simply execute the following command in Terminal:

ruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homebrew/go/install)"

It will first install the XCode Command Line Tools (don’t worry if you already have it, just hit “install” and let it do it’s thing) and then once the Xcode dialog disappears, hit [any] key in Terminal and it will auto-download and auto-install itself. Once its all finished (and it can take a few minutes, just be patient), simply re-execute the command to install RVM Ruby.

‘belongs_to’ and ‘has_one’ Differentiated

One of the more common confusions with ActiveRecord associations is the difference between the `has_one` and `belongs_to` relationships.

However, they are not interchangeable, and there are some serious differences. A `belongs_to` can only go in the class that holds the foreign key whereas `has_one` means that there is a foreign key in another table that references this class. So `has_one` can only go in a class that is referenced by a column in another table.

So this is wrong:

class Transaction < ActiveRecord::Base
  # The transactions table has a order_id  
  has_one :order                
end

class Order < ActiveRecord::Base
  # The orders table has a transaction_id
  has_one :transaction          
end

So is this:

class Transaction < ActiveRecord::Base
  # The transactions table has a order_id
  belongs_to :order             
end

class Order < ActiveRecord::Base
  # The orders table has a transaction_id
  belongs_to :transaction     
end

For a two-way association, you need one of each, and they have to go in the right class. Even for a one-way association, it matters which one you use, and which direction you use it:

class Transaction < ActiveRecord::Base
  # This table has no foreign keys
  has_one :order             
end

class Order < ActiveRecord::Base
  # The orders table has a transaction_id
  belongs_to :transaction     
end

Ruby Script to Import Google Contact Photos From Gravatar

Google Contact photos are a much neglected feature of the Google Stack. It really adds to the user experience when you see each of your contact photos when you make or receive a call. However, it can be a real pain (especially if you have hundreds of contacts).

But I had an idea recently, to try and match my Google Contact emails with Gravatar and try to auto-populate some of the dozens of contacts that didn’t already have a photo (after all a Gravatar is better than nothing).

So I wrote a Ruby script to find my contacts missing a photo and try to update it with a Gravatar (wherever possible). NB: You may need to first install the GData (Google Data) gem by opening a Terminal window and issuing: sudo gem install gdata.

#!/usr/bin/env ruby

# Google Contact Photos - Gravatar Importer
# Written by Ashley Angell
# http://ashleyangell.com
# Licenced under Creative Commons with Attribution

require "rubygems"
require "gdata"
require "rexml/document"
require "digest/md5"
require "net/http"
include REXML

none = 'd5fe5cbcc31cff5f8ac010db72eb000c'
user = ARGV[0]
pass = ARGV[1]

client = GData::Client::Contacts.new
client.clientlogin(user, pass)
data = client.get("https://www.google.com/m8/feeds/contacts/#{user}/full?max-results=10000")
myxml = Document.new data.body
p "contacts"
puts "-"*70
i = 0
myxml.each_element("feed/entry") do |e|
  begin
    gd = e.elements['gd:email']
    if !gd.nil?
      email = gd.attributes['address'].downcase
      hash = Digest::MD5.hexdigest(email)
      image_src = "http://www.gravatar.com/avatar/#{hash}"
      nil_image = false
      image_element = e.get_elements("link[@rel='http://schemas.google.com/contacts/2008/rel#photo']")[0]
      if !image_element.nil? and image_element.attributes['gd:etag'].nil?
        data = nil
        md5 = nil
        Net::HTTP.start(URI.parse(image_src).host) do |http|
          resp = http.get(URI.parse(image_src).path)
          data = resp.body
          md5 = Digest::MD5.hexdigest(data)
          File.open("#{email}.png", 'w') do |f|
            f.puts data if md5 != none
          end
        end
        md5 = Digest::MD5.hexdigest(data)
        if md5 != none
          puts "#{email} > #{image_src}"
          client.put_file(image_element.attributes['href'], "#{email}.png", 'image/png')
          i = i + 1
        else
          puts "#{email} > no match"
        end
      else
        puts "#{email} > skipped (already has photo)"
      end
      File.delete("#{email}.png") if File.exists?("#{email}.png")
    end
  rescue Exception => ex
    puts ex
  end
end
puts "Updated #{i} contact photos"

To execute it, simply copy and paste this into a text editor (or download it and unzip) and from Terminal (command) window and execute the following commands:

sudo chmod +x googlegravatarimporter.rb [Enter]
./googlegravatarer.rb your.address@gmail.com your_password [Enter]

It will cycle through your Google Contacts and indicate what action was taken. For me, surprisingly updated a few dozen contacts (even more than I expected).

I’ve posted this here for others that might want to do the same thing but cannot be bothered writing the script for it. Consider it posted here under Creative Commons with Attribution.

‘File not found: lib’ Error installing Rails Gem

I recently had a problem trying to install Rails 3 on my MacBook with a fresh OSX Snow Leopard:

sudo gem install rails
Password: {entered}
Successfully installed rails-3.0.7
1 gem installed
Installing ri documentation for rails-3.0.7...
File not found: lib

Turns out this is a somewhat common problem.  But it seems that the solution is easy, just manually reinstall RDoc. To do this run these 3 commands:

sudo gem install rdoc-data
sudo rdoc-data --install
sudo gem rdoc --all --overwrite

The last line in particular will re-generate all the documentation for your installed gems (including Rails) and can take a while, but you should be able to confirm the fix by reissuing the Rails gem install command:

sudo gem install rails

shows that rails now installs properly and says that it has installed both ri and RDoc documentation without issue.

Adding Wiki Style Functionality to Your Rails Site Using 'acts_as_versioned'

If you need to add basic wiki style functionality to your Ruby on Rails models, there is a really easy way to get similar model versioning without having to resort to cutting the code yourself.

The acts_as_versioned ‘plugin’ has been available for quite some time, but its been made far better by it now becoming a gem instead of an old-school plugin. The authors have gone to considerable effort to make it as painless as possible to use.

This post, is designed to give you a brief over-view into how to get up and running with with models which ‘acts_as_versioned’.  Because its the current version (at time of posting) and because its awesome, this walk-though assumes that you are using Rails 3, not 2.  The instructions for Rails 2 sites are similar, but you’ll need to tweak this for it to work.

First, you need to grab the gem:

sudo gem install acts_as_versioned

Next, add the dependency to the ‘Gemfile’, it doesn’t matter too much where it goes, I stuck it somewhere in the middle:

gem 'acts_as_versioned', '0.6.0'

Next, just under the ‘ActiveRecord::Base’ line in the model’s class file, instruct the class that its to act as a versioned model.

class Article < ActiveRecord::Base
  acts_as_versioned
end

Then, in the migration file you need to execute the model's method to create the version table.  This is key because the acts_as_versioned gem actually creates an additional database table to house all the previous versions of a given record.  Obviously, you need to delete the table is the schema is taken down.  My migration now looks like:

class CreateArticles < ActiveRecord::Migration
  def self.up
    create_table :article do |t|
      t.string :title
      t.string :body
      t.integer :user_id

      t.timestamps
    end
    Article.create_versioned_table
  end

  def self.down
    drop_table :articles
    Article.drop_versioned_table
  end
end

The key method is the

Article.create_versioned_table

which creates the version table of the model. Now, get rake to create the database:

 rake db:migrate

Thats it!  Its done.  Using acts_as_versioned is simple. I'll provide some examples, where '@article' represents an instance of a model setup 'acts_as_versioned'. To find the current version of an article you can use the version property:

@article.version 

But just performing a normal ActiveRecord lookup returns the most current version anyway, so to revert to a previous version use the revert_to method on an article instance:

@article.revert_to(version_number)

You can save (just like you've done a hundred times before) a previous version as the current on by using the save method. The save on a reverted articles will just create a new version.

To get the number of versions:

@article.versions.size

Since '@article.versions' returns an array of versions, you can do neat things like this:

History

<% for version in @article.versions.reverse %> Version <%= version.version %> <%= link_to '(revert to this version)', :action => 'revert_to_version', :version => version.id, :id => @article %>
<% end %>

Obviously for this to work, you'd need to create a 'revert_to_version' action in the appropriate controller, but you get the idea.

acts_as_versioned is an amazing piece of work, and aside from the wiki-like functionality it gives you for very little effort, I can imagine scenarios such as audit and trace logs and "undo" features which could really benefit from this little gem.