Ruby on Rails with Dan Watson


Programming in Ruby tutorials and examples

Install Gimp 2.8 on Ubuntu 12.04

gimp screenshot


Here is a quick and easy way to install the new release of Gimp 2.8 on Ubuntu. One of the great new features of this release is you can now work in a single window rather than multiple windows. To activate single window mode just go to the tool bar and select window -> Single-Window mode, this is just one of the many new features with this release.

Release notes for the latest 2.8.2

  • Mention that the image was exported in the close warning dialog
  • Fix the visibility logic of the export/overwrite menu items
  • Remove all “Use GEGL” menu items, they only add bugs and zero function
  • Improve performance of display filters, especially color management
  • Fix the image window title to comply with the save/export spec and use the same image name everywhere, not only in the title
  • Fix positioning of pasted/dropped stuff to be more reasonable
  • Fix remembering of JPEG load/save defaults
  • Lots of bug fixes
  • List of translation updates
1
2
3
4
5
6
sudo apt-get autoremove gimp gimp-plugin-registry

sudo add-apt-repository ppa:otto-kesselgulasch/gimp
sudo apt-get update
sudo apt-get install gimp
sudo apt-get install gimp-plugin-registry

Rails - Rspec - Testing Your Modules

I have been working on a project recently where modules are used extensively to share behaviour between model classes. I was looking to use an example from the system but they were all overly complex and detracted from the subject - testing modules. So in the following contrived example I will show you how to test the behavior of a module using rspec. The following “Pointless” module adds a class method which will scramble a class name…. doesn’t get more pointless than that!

1
2
3
4
5
6
7
8
9
module Pointless
  extend ActiveSupport::Concern

  module ClassMethods
    def scrambled_class_name
      Digest::MD5.hexdigest(name)
    end
  end
end

Below the module is mixed into two active record classes.

1
2
3
class Post < ActiveRecord::Base
  include Pointless
end
1
2
3
class Comment < ActiveRecord::Base
  include Pointless
end

When testing modules I tend to add a folder under the spec directory called modules. I then use the shared_examples_for group and define specs within the block. When calling described_class it returns the class that the module has been mixed into within the current it_behaves_like context.

spec/modules/pointles_spec.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
require 'spec_helper'

shared_examples_for Pointless do
  context "class methods" do
    it 'should be able to scramble the class name using md5' do
      described_class.scrambled_class_name.should == Digest::MD5.hexdigest(described_class.name)
    end
  end
end

describe Post do
  it_behaves_like Pointless
end

describe Comment do
  it_behaves_like Pointless
end

It’s then just a matter of using describe for each class the module has been mixed into and call it_behaves_like Module, then the specs for the module will be run in the context of the class.

Ruby Development Quick Tip - Use the Ssh-forever Gem - Stop Typing Your SSH Passwords

I just wanted to share a quick tip. A friend of mine asked why when using SSH does it not ask me for my password.

The quick answer is I use the ssh-forever gem.

By using this gem you only have to input your SSH passwords once and then they will be remembered for all future SSH connections (which is great when using deployment tools like capistrano or vlad - as you don’t want to keep entering your password everytime you deploy).

Firstly install the gem.

1
2
3
4
 (if you are using rvm - install it in the global gemset)
 rvm use gemset global

 gem install ssh-forever

Then its as simple as

1
 ssh-forever root@myserver.net 

You will be prompted to enter you SSH password for the last time. Future connections made will not require a password when connecting from your machine.

Ruby Nested Hash - Deep Fetch - Returning a (Default) Value for a Key That Does Not Exist in a Nested Hash

Ok so this is a follow on post for Ruby Hash - Fetch - Returning a (Default) Value for a Key That Does Not Exist which I wrote yesterday.

Basically I found that you can use the fetch method on a hash to either retrieve a value for a key or return a specified value. In the posts comments someone mentioned that it was useless for nested hashes, which is true. It turns out that it is not that hard to implement the behaviour of fetch for fetching a nested key / value pair.

For this I have added a few methods to the Hash class (if your using rails you could make this an initializer). The deep_fetch method will behave exactly the same as fetch but search the hash at all levels for a keys value.

1
2
3
4
5
6
7
8
9
10
class Hash
 def deep_fetch(key, default = nil)
   default = yield if block_given?
   (deep_find(key) or default) or raise KeyError.new("key not found: #{key}")
 end

 def deep_find(key)
    key?(key) ? self[key] : self.values.inject(nil) {|memo, v| memo ||= v.deep_find(key) if v.respond_to?(:deep_find) }
  end
end

Here is an example of a nested hash we are going to work with.

1
hash = { :search => "Search Term", :order => :desc, :extra => { :user => { :uid => 12345, }}}

It will find a keys value at the first level of the hash (this is the same behaviour as fetch).

1
hash.deep_fetch(:search)  # => "Search Term"

If no default value is passed as the second argument a KeyError will be raised if the key is not found (this is the same behaviour as fetch).

1
hash.deep_fetch(:no_key)  # => "KeyError: key not found no_key

It will return a default value for a key that does not exist if the default argument is passed to the method.

1
hash.deep_fetch(:no_key, :my_value) # => :my_value

It can accept a block for calculated default values.

1
hash.deep_fetch(:no_key) { 5 + 5 } # => 10

It can fetch a value for a deeply nested key.

1
2
hash.deep_fetch(:user) # => { :uid => 12345 }
hash.deep_fetch(:uid) # => 12345

Ruby Hash - Fetch - Returning a (Default) Value for a Key That Does Not Exist

I was looking at some ruby code I wrote a few days ago and something didn’t sit right with me. I had a bit of a code smell when setting a default value for a hash key if the key didn’t exist.

The scenario… there is a hash that has a search key which holds information for a search term, optionally the order key may be set also.

1
  hash = {:search => "ruby hashes" }

Initially when the order key had not been set I would perform a check to see if they key existed then using the ternary operator set a default value. I think it looks a bit ugly though!

1
  order = hash.key?(:order) ? hash[:order] : :desc

How have I not heard of the fetch method before? Fetch takes a key argument which will be used to look up the key in the hash, optionally it takes a second parameter which is the value to return if the key has not been set.

1
  order = hash.fetch(:order, :desc)

A small refactor which I think looks much nicer. This may be obvious to some, but it was one of those methods I had just never used!

Rails ActiveRecord - Batch Updates

I am currently writing an application that requires a high level of performace. This means that every line of code written has to be scrutinised and performace tested. I am finding myself needing to take a different approach for the simplist of code in order to squeeze out every last drop of speed.

Imagine you need to update an attribute on a collection of items.

1
2
3
  Tag.where(:is_featured => true).each do |tag|
    tag.update_attribute(:is_featured, false)
  end

This is bad for a few of reasons. Firstly we have to load each record into memory and secondly a seperate update statement is fired for every record updated. If there are lots of records your application will feel the performance hit.

If you want to do this in one single sql call it can be done using the update_all method.

1
  Tag.update_all({ :is_featured => false }, {:is_featured => true })

The first argument are the attributes to update and the second is the filter conditions for the query. So for the case in hand the sql generated will be.

1
  UPDATE `tags` SET `is_featured` = 0 WHERE `tags`.`is_featured` = 1

The only drawback to this is that you model callbacks will not be triggered, but luckily in my case this is not an issue.

Devise - Omniauth - Facebook - Getting Extra Permissions

When using devise and omniauth for authentication sometimes you need to require more permissions from facebook. This is useful when you want to later use the authentication code from facebook do such things as posting to the users wall (I recommend the Koala Gem for this).

Within the devise config you will probably already have your facebook omniauth provider setup. After passing the secret key you just need to pass a scope requesting the additional permissions required for your application.

config/initializers/devise.rb
1
  config.omniauth :facebook, 'app_id', 'secret_key', { :scope => "publish_stream, offline_access, email" }

When your user is now setup or authorized from facebook make sure you save the code parameter against the user, this is passed back to your omniauth callbacks controller. Here is an example of mine below.

app/controllers/users/omniauth_callbacks_controller.rb
1
2
3
4
5
6
7
8
9
 class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
   include Devise::Controllers::Rememberable

   def facebook
     @user = User.configure_facebook_user(request.env["omniauth.auth"], params[:code])
     remember_me @user
     sign_in_and_redirect @user, :event => :authentication
   end
 end

Also below I have included my class methods from my user model that takes care of saving the user (I hope this helps someone).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
def facebook_config
  YAML.load_file("#{Rails.root}/config/facebook.yml")[Rails.env]
end

def facebook_client(access_token)
   Koala::Facebook::API.new(access_token)
end

def configure_facebook_user(authorisation_hash, code)
  user = User.where(:email => authorisation_hash.info.email).first

  unless user
    user = User.create(:email => authorisation_hash.info.email,
                       :first_name => authorisation_hash.extra.raw_info.first_name,
                       :last_name => authorisation_hash.extra.raw_info.last_name,
                       :gender => Gender[authorisation_hash.extra.raw_info.gender.to_sym],
                       :date_of_birth => nil,
                       :location => authorisation_hash.extra.raw_info.hometown.name,
                       :about => authorisation_hash.extra.raw_info.bio,
                       :password => Devise.friendly_token[0,20]
                      )
  end
  user.role = Role[:member] unless user.role
  begin
    user.token = User.facebook_oauth_client.get_access_token(code)
  rescue
    #External api call rescue all!
  end
  user.provider = authorisation_hash.provider
  user.uid = authorisation_hash.uid
  user.save
  user.confirm!
  user.remember_me!
  user
end

def facebook_oauth_client
  Koala::Facebook::OAuth.new(User.facebook_config['app_id'],
                             User.facebook_config['secret_key'],
                             "#{User.facebook_config['callback']}/users/auth/facebook/callback")
end

Octopress - Category List Plug-in

I have just switched two blogs over to use Octopress, both dotnetguy.co.uk and also paz.am/blog.

One thing that was missing “out of the box” was the ability to include a list of categories in the sidebar with a link. Fortunately Octopress (well actually Jekyll) is written in such away that creating a plug-in to do this is very simple.

Firstly we need to write a little ruby code. Add a file to the plugins directory called category_list_tag.rb. This plug-in will take the category data from the site and generate list items for each category. On line 17 the category_list tag is then registered and made available to the liquid templating engine.

category_list_tag.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
module Jekyll
  class CategoryListTag < Liquid::Tag
    def render(context)
      html = ""
      categories = context.registers[:site].categories.keys
      categories.sort.each do |category|
        posts_in_category = context.registers[:site].categories[category].size
        category_dir = context.registers[:site].config['category_dir']
        category_url = File.join(category_dir, category.gsub(/_|\P{Word}/, '-').gsub(/-{2,}/, '-').downcase)
        html << "<li class='category'><a href='/#{category_url}/'>#{category} (#{posts_in_category})</a></li>\n"
      end
      html
    end
  end
end

Liquid::Template.register_tag('category_list', Jekyll::CategoryListTag)

Now we need to create the category list (category_list.html) template in source/_includes/asides. We now use the “category_list” tag we registered in the plug-in above.

category_list.html
1
2
3
4
5
6
<section>
  <h1>Categories</h1>
  <ul id="categories">
    {% category_list %}
  </ul>
</section>

Finally we just need to add the new sidebar template to the default_asides configuration within the _config.yml.

_config.yml
1
default_asides: [asides/category_list.html, asides/recent_posts.html, asides/twitter.html, asides/delicious.html, asides/pinboard.html, asides/googleplus.html]

And that’s all she wrote! I think Octopress / Jekyll is an excellent blog engine / static site generator, and being able to hack away and write simple plug-ins quickly makes it my number one choice… for now.

Introducing Kue - a Rails Ready Key Value Store That Uses ActiveRecord Under the Hood

A few weeks ago I wrote a post on how I had implemented a simple key value store using activerecord.

I received a lot of feedback not only via the comment’s on the post but also by email. As so many people showed interest I decided to create an activerecord backed key value store gem called kue encompassing some of the idea’s and thought’s that people had brought to my attention.

Getting setup with kue is easy as it has a rails generator to copy over the migration needed in order to setup the underlying key value storage table.

rails generate kue:install
rake db:migrate

When you want to set or retrieve any arbitrary keys value then you can do so by calling on the KueStore class.

#Set the value of the key
KueStore[:any_key_name_you_can_think_of] = "Any object you can dream up"
#Retrieve the value of the key 
KueStore[:any_key_name_you_can_think_of] 

There is also a helper method to check if a key already exists.

KueStore.exists?(:my_class_instance)

One of the nice things about kue is it can store any object you can think of complex or simple!

 KueStore[:my_class_instance] = Foo.new(:name => 1)

Let me know what you think. Pull requests are always welcome!

ActiveRecord STI - How to Prevent the Base Class Being Saved.

When using ActiveRecord and Single Table Inheritance sometimes it may not be desirable to have the base class ever persisted to the database, which by default is able to occur.

In the following contrived example we can see that we have an animal base class as well as dog and cat classes that inherit from animal.

class Animal < ActiveRecord::Base
  
end

class Dog < Animal
  
end


class Cat < Animal
  
end

Here is the migration that is used back these objects. Take note of the type column. The type column will be saved with the name of the class, in this case either Dog or Cat depending on which type of object is being persisted.

create_table :animals, :force => true do |t|
  t.string   :name
  t.string   :type
end
Animal.create(:name => "Fido")
=> # 

As the example above shows the Animal class is able to be saved to the database. This may not be particularly desirable (dependant on requirements) as you may want to lock down your model so only the inherited classes can be persisted (in this case Dog or Cat).

So how do we stop this?

Firstly make sure you application loads the following folder by adding app/modules to your autoload_paths in your application.rb

module ApplicationName
  class Application < Rails::Application
    config.autoload_paths += %W(#{config.root}/app/modules)
  end
end

Then add the following folder structure to your applications app folder.

--app
---modules
----active_record
-----extensions
-------abstract_class.rb

In the abstract_class.rb file add the following code. This is a module that extends ActiveSupport::Concern.

module ActiveRecord
  module Extensions
    module AbstractClass
      extend ActiveSupport::Concern
      
      included do
        before_save :abstract_class?
      end
  
      def abstract_class?
        raise "Do not try to save #{self.class} as it is an abstract class" if self.read_attribute(:type).nil?
      end
    end
  end
end

Using the module and including it into any base class (in this case Animal) will stop it from ever being able to be persisted to the database. It works because the base class is never saved with a type so we are able to check for this and then throw an error if necessary.

class Animal < ActiveRecord::Base
  include ActiveRecord::Extensions::AbstractClass
end
Animal.create(:name => "Fido")
RuntimeError: Do not try to save Animal as it is an abstract class

I really like this kind of model level constraint as it locks down your data API for other developers you share code with, without the need for too much documentation or explanation.