by Michel Martens on December 15, 2009
You are given the task of validating that no two users register with the same name.
In ActiveRecord it can be implemented like this:
validates_uniqueness_of :name
You may now add an index to your database and consider your task done, but it’s also true that you can improve the user experience by using a better error message:
validates_uniqueness_of :name, :message => "The name {{value}} is taken. <a href="/login">Log in</a> instead?"
Did you see the use of {{value}} in there? That’s because ActiveRecord’s DSL for validations operates on a class level, and that means that when you are declaring the validation, you don’t have access to the instance you will be dealing with. Note also that there’s HTML in the error message. It’s nice to point the user in the right direction, and here it only makes sense to send the user to the login page. But HTML in the models is wrong in many levels, not to mention that the URL helpers are not available there.
It would make much more sense to declare the validations at the instance level, something ActiveRecord allows with the validate method. If we had validates_uniqueness_of as an instance method, this would be possible:
def validate
validates_uniqueness_of :name, :message => "The name #{name} is taken. <a href="/login">Log in</a> instead?"
end
A detail here is that we can build the message with Ruby interpolations instead of the {{value}} macro. The HTML is still there, but I will deal with that in another post.
Code smells in redundant DSLs
Another example of why a class level DSL for validations is a bad code smell:
validates_presence_of :card_number, :if => :paid_with_card?
def paid_with_card?
payment_type == "card"
end
What’s wrong here? The validations DSL is reimplementing Ruby functionality, but not because it’s an improvement but because it’s operating on the wrong scope. Returning to the instance level approach, this is how it would look:
def validate
validates_presence_of :card_number if paid_with_card?
end
There are two other examples in the Rails guides, which I reproduce here:
validates_presence_of :surname, :if => "name.nil?"
As you may know, this evaluates the string within the instance. Needless to say, it’s another case where the DSL reinvents the wheel for no good reason. The counter example:
def validate
validates_presence_of :surname if name.nil?
end
And now the proc approach:
validates_confirmation_of :password,
:unless => Proc.new { |a| a.password.blank? }
The counter example:
def validate
validates_confirmation_of :password unless password.blank?
end
As you can see, these solutions are shorter and make the DSL look superfluous. It means that the DSL is unnecessary.
When you count the lines of code of your models, you should take into account how much code you are injecting. Your models could be hundreds of lines shorter if irrelevant DSLs like this one were removed.
by Michel Martens on December 11, 2009
I had a very interesting conversation with Fictorial about how Ohm treats sets, lists and counters differently than normal attributes.
From the documentation (updated after the conversation):
The attributes declared with attribute are only persisted after calling save. If the object is in an invalid state, no value is sent to Redis (see the section on Validations below).
Operations on attributes of type list, set and counter are possible only after the object is created (when it has an assigned id). Any operation on these kinds of attributes is performed immediately, without running the object validations. This design yields better performance than running the validations on each operation or buffering the operations and waiting for a call to save.
The idea of buffering the operations and waiting for a save is from Fictorial, who is porting Ohm to Node.js. Here is what he does:
What I did in NOM is make changes to the local/client-side object while at the same time buffer (in the same order) the commands needed to realize the local changes remotely in Redis. For instance, a List object has a push method. This is JS so the local object is an Array which is updated with the corresponding .push. At the same time, I buffer a “RPUSH key length\r\nvalue\r\n”. Then, if the validation passes, I send the buffered commands.
I know from my experience with Ohm that I’m comfortable with the current approach, and if I need to check for validity before operating on lists, sets or counters, I can use the pattern described in the docs.
Thoughts?

Ok we’re a few days late, but http://www.sharespost.com has just launched. Citrusbyte helped the company get to an internal beta in only 6 weeks with a lean team of two. We then ramped in their new internal developer who pushed the site to live.
Check out more about the company here: http://www.crunchbase.com/company/sharespost
And the press: http://www.sharespost.com/pages/press
SharesPost makes private equity liquid by efficiently matching buyers, sellers of private company stock and giving them the information, tools and process to make transactions easy and safe. At SharesPost you can download research reports and corporate documents for hundred’s of private companies, including Facebook, Twitter and LinkedIn. Plus, see prices from previous transactions. When you’re ready, connect directly with buyers and sellers of private company shares without brokers or their commissions. SharesPost provides you with automated contracts and integrated e-signature and escrow services to handle transfer restrictions like company rights of first refusal and help process your transaction.
by Damian Janowski on June 3, 2009
So, you are a good citizen in the Ruby community. You like to find patterns, extract them to a gem and make everyone benefit from it. You release early and release often. But you’re only releasing to GitHub, and suddenly you realize why: releasing to RubyForge is a huge pain, completely outside of your workflow.
Meet Joe, the gem publisher
Joe builds on top of Thor’s awesomeness to take you from a gem specification to world domination in a single step:
$ thor joe:release
Given that you have a gemspec in place, Joe will build your gem and release it to RubyForge right away. The necessary steps to achieve this are broken up as Thor tasks just in case you need any of them separately. Check out the README to find out more.
What about Hoe?
Of course, there’s Hoe. But it introduces another level of indirection by adding a number of artifacts to circumvent actually writing a gemspec. If you want to have a code generator and a bunch of *.txt files instead of a simple and streamlined gemspec, by all means make sure to give Hoe a try. Chances are you already have it installed: until recently, Hoe used to produce gems that depended on Hoe itself. That’s why you’re likely to get something out of gem list hoe even if you’ve never used it to write a gem. Yeah, creepy.
Otherwise, spare yourself the hassle and try Joe, a guy that honors your gemspec and does the work for you. After all, maintaining your gemspec is not that hard.
Getting started
Check out Joe’s homepage in our labs and start rolling.