Writing YAML files
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
Nested Forms
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 »
Gem cleanup
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.
RSpec, Shoulda, and custom matchers
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!
I’m slacking and I’m sorry
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.