Recently, after reading Object on Rails, I started thinking and experimenting with various ideas of making Rails applications code cleaner. Here’s one of these ideas.
Let’s imagine we have two model classes, connected with a has-many/belongs-to relation, e.g.:
# file user.rb
class User < ActiveRecord::Base
has_many :posts, dependent: :destroy
# rest of the user stuff
# file post.rb
class Post < ActiveRecord::Base
belongs_to :author, class: "User"
The above code is probably how most of Rails programmers would go about implementing a “user has many posts/post belongs to its author” scenario. It’s the tutorials-approved way. But when you look at it from a architectonic point of view, you have just created a circular dependency.
I always have a problem parsing Rails‘ named routes in my head. It usually takes me a lot of time and effort to decide which controller action or view file is responsible for given path. Of course, it’s easy to tell when you look at:
that you probably should go to
users_controller.rb and find
edit action and
views/users/edit.html.haml is the right view file. But when nested routes, prefixes and non-RESTful actions all come to play, you might end up with a monster like:
Don’t laugh, this is real. So, what’s going on here? What is the action name? Are those “employer” things prefixes or nested routes? Where do I find the view? To answer all these questions, the Rails Routes TextMate bundle was born.
Here’s a quick tip for enhancing your test writing productivity: use
assert‘s last parameter, the message. Virtually all
assert_... methods accept it. You may have noticed in the docs that the last parameter is always
message = nil or
message = "". Too bad the docs don’t give examples on how to use this message. So, let me fix that.
Shoulda gem is great not only because it provides you with a very clean and natural way of organizing tests with
should building blocks, but it also comes with quite a large set of predefined macros that mirror Rails’ validations, relations etc. What’s even better — it’s very easy to create your own macros to further speed up test writing. Modern versions of Shoulda gem allow to do it in a clean and modular way. That’s great news if you are serious about TDD because for every substantial codebase you will end up with even bigger pile of testing code, so any tool helping in encapsulating common test logic or patterns is priceless.
This article is a tutorial on writing custom Shoulda macros: from very simple to quite complex.
Small tip: when you happen to be running Rails in a console that doesn’t understand ANSI codes (those pesky
←[0;1m that clutter your display), like for example Windows’
cmd, you can turn them off with:
if RUBY_PLATFORM =~ /mswin32/
ActiveRecord::Base.colorize_logging = false
Put this in
config/environments/development.rb and restart
Took me a while to find it, so I thought I’d post it for posterity :)
Stubbing and mocking in unit tests is generally considered a Good Thing. It can make your tests run faster, it helps you not to cross boundaries. But it also makes your tests more brittle.
The reason for this is simple. If you want to stub out some method, you have to do it very precisely. You have to know the underlying implementation and choose a very concrete instance and method for stubbing. This makes your test very tightly coupled to the implementation details of tested class. And tightly coupled is brittle. Let’s look at some trivial example:
By turning off the
Because they’re slow! Didn’t you read the comment in your
test_helper.rb? Yes, this one:
# Instantiated fixtures are slow, but give you @david where otherwise you
# would need people(:david). If you don't want to migrate your existing
# test cases which use the @david style and don't mind the speed hit (each
# instantiated fixtures translates to a database query per test method),
# then set this back to true.
But what about those nice @david variables?
They must be gone. Sorry. The tests are slow because of them. The above comment explains why.
…or: how to put class scope to use
The class scope, i.e. the space inside class declaration, but outside method definitions, is a no man’s land in many languages (particularly in Java). By this I mean that you can define methods, variables, and other classes there and you can even execute some code (in variable initializations) but nothing more. Fortunately, in Ruby empty space between method definitions can be filled with all kinds of useful, executable code. Let’s check a few examples.