Adventures with Ruby

Writing YAML files

View Comments

A short one for today: How do I write YAML files?

Well, to get the prettiest results, I do something like this:

def write(filename, hash)
  File.open(filename, "w") do |f|
    f.write(yaml(hash))
  end
end

def yaml(hash)
  method = hash.respond_to?(:ya2yaml) ? :ya2yaml : :to_yaml
  string = hash.deep_stringify_keys.send(method)
  string.gsub("!ruby/symbol ", ":").sub("---","").split("\n").map(&:rstrip).join("\n").strip
end

Read the rest of this entry »

Written by Iain Hecker

May 15th, 2009 at 2:18 pm

Posted in iain.nl

Nested Forms

View Comments

The old subject of nested forms comes back again to hunt me. Rails 2.3 has the new and shiny accepts_nested_attributes_for feature. I like it, but there are some things to take into consideration. Adding a child object through javascript remains a bitch to tackle. So I sat down and wrote some javascript. Here is what I came up with. Not sure if I’m going to release this a plugin though.

First of, build the models. I have a project with many stages:

[sourcecode language='ruby']
class Project < ActiveRecord::Base
validates_presence_of :name
has_many :stages
accepts_nested_attributes_for :stages, :allow_destroy => true
end

class Stage < ActiveRecord::Base
validates_presence_of :title
belongs_to :project
end
[/sourcecode]
Read the rest of this entry »

Written by Iain Hecker

May 2nd, 2009 at 2:40 pm

Posted in Uncategorized

Gem cleanup

View Comments

I was browsing through the gem documentation today, and I found a command that I didn’t know existed.

sudo gem cleanup

It removes old versions of your installed gems. You can of course specify the gems you’d like to cleanup.

Written by Iain Hecker

April 26th, 2009 at 12:21 pm

Posted in Uncategorized

RSpec, Shoulda, and custom matchers

View Comments

I have been playing with the matchers that Thoughtbot’s Shoulda provides, and they are very cute!

For instance, a controller can be easily tested like this:

describe ArticlesController do
 
  integrate_views
 
  describe "the index action" do
 
    before :each do
      stub(@article = Article.new).id { 1337 }
      mock(Article).all { [@article] }
      get :index
    end
 
    it { should route(:get, articles_path).to(:action => :index) }
    it { should respond_with(:success) }
    it { should render_template(:index) }
    it { should_not set_the_flash }
    it { should assign_to(:articles).with([@article]) }
 
  end
end

As you see I’m a fan of rr as well. I love the sleek and concise syntax it offers, just as the Shoulda matchers.

So, now what?

Well, I don’t like to spec views separately. It’s too much of a drag to set up all the required instance variables, because there tend to be a lot of them. That’s why I use the integrate_views command. I do want to spec some essential elements rendered in the view. Just knowing that no exceptions were thrown is not always good enough.

The solution is the have_tag matcher. This is actually a wrapper around assert_select, allowing you to use CSS selectors to check your view. I ended up testing links to certain actions, to ensure all the actions are reachable for the user. For example:

it { should have_tag("a[href=#{article_path(@article)}]") }

Yuck! That is a lot of noise! The whole use of RSpec is to create human readable tests. Also, there is a lot that can go wrong here. I will easily forget one or more of those differently shaped brackets. I want to write something like:

it { should have_link_to(article_path(@article)) }

Much cleaner! Making a matcher for this isn’t that difficult:

module CustomLinkMatcher
 
  include Spec::Rails::Matchers
 
  def have_link_to(url)
    AssertSelect.new(:assert_select, self, "a[href=#{url}]")
  end
 
end

Don’t forget to activate it, though:

Spec::Runner.configure do |config|
  config.include CustomLinkMatcher
end

So, why go through all this trouble? Why should I even care? I mean, the have_tag selector isn’t that unreadable, just a bit cluttered. Well, I found that the ease of which you can type specs is directly related to how extensive you test. If a test is difficult to type, hard to read, or feels repetitive, most people (with possible exception of Bryan Liles ;) ) will get annoyed with it and don’t do it anymore.

To give myself as an example. I never cared much about heckle. Heckle could mutate so much code, I soon stopped caring. Now, with the matchers Shoulda gives me, I like running Heckle! I know keeping Heckle happy shouldn’t be a goal, and I accept certain things Heckle will heckle me about even now, but writing specs like this really made my tests much more robust!

So, in conclusion: if you find yourself hating to write certain specs, try to refactor your specs so it becomes easy and fun! Try to write tests as you would like your tests to be written. Testing should be fun! Keep it that way! Use every gem, tool and technique you have to do so!

Written by Iain Hecker

April 11th, 2009 at 2:37 pm

Posted in Uncategorized

I’m slacking and I’m sorry

View Comments

I was about to do lots of work for the i18n-community, improving the website, managing the fork requests of Globalize 2, improving the official Rails guide and more. But instead, I just slowed down developing in my spare time, letting the community down in the process.

Now it’s not that they need me, but I felt like I was making a contribution. I felt obligated to do as much open source as possible and my already busy schedule kept getting busier. Then suddenly I couldn’t get myself to do it anymore.

Lately, what I do when I come home after work is read up on my RSS feeds, check the i18n mailing list to see if I can be of any assistance, and more than once just read a book at night. Finding a bit of a balance between work and relaxation. And this is a more pleasant schedule for me and one I can keep up with.

I also had a streak of bad luck these last few weeks. My washing machine died (it was 23 years old, so it didn’t really come as a big surprise), my server died, my graphics card in my desktop died, my heating is still dead (a mechanic is coming on Monday), and I have caught an annoying cold.

So, I am sorry about my absence. Hopefully it’ll improve during the coming months. All the much respect to all those programmers that do continue working at night for days on end.

So, what have I been doing?

Well, I worked through the fork queue of my http_accept_language plugin, merging in some improvements and making it compatible with Rails 2.3.

Furthermore, I’m busy making some changes to Ryan Bates’ Nifty generators so that they don’t use fixtures anymore, use Authlogic, and add some minor adjustments to what I found to be very useful when trying to do RAD. You shouldn’t use it just yet.

And finally, I’m trying to come up with a way of making forms that doesn’t hurt. ActionView::FormBuilder is nice, but if you need a lot of forms, it can become tedious. I’m trying to automate it more, while keeping as much flexibility as possible. It’s a difficult process to find out what actually is the handiest. I am making progress though.

And finally, I will be trying to blog a bit more. I’m ashamed that this is the first post of 2009.

Written by Iain Hecker

March 13th, 2009 at 12:44 pm

Posted in iain.nl

Fork me on GitHub