ActiveRecord is an extremely powerful tool, allowing us as developers to be more productive by writing less and doing more. Most of the time this less works to our advantage, but sometimes less is not more.
Imagine you have the following models:
Notice that we have a Book
model which has title and author attributes,
as well as a Chapter
model which references a Book
(via book_id) and
title attributes.
Since ActiveRecord provides easy interfaces for querying from our database, we
can quickly find all Books
by an author, title, or containing a Chapter
.
If you were paying close attention to the above statements, you may have noticed that two of the arguments were a hash, but one used a string. ActiveRecord allows developers to pass a SQL string to be executed, among other things. For the most part, passing a string into ActiveRecord’s querying utilities will work as expected…for the most part.
Once we get into more complex queries, ActiveRecord may help us avoid problems
that we’re not always weary of. Notice how both of our Book
and Chapter
models have a title
attribute, what would happen if we tried to join
these
two tables together while querying based on title
?
Ah, an error! It looks like our database did not know which table’s title
attribute we were interested in using. Now lets try the same method, but use a
hash instead.
Nil? Well, at least this didn’t raise any exceptions. To better understand what happened, let’s take a look at the generated SQL.
Near the end of the query, we see that ActiveRecord automagically selected our
Book
model to be queried upon. This is very helpful of Rails, but we didn’t
want to query by our Books
title, but on our Chapters
title. Enter nested
hashes.
Perfect! Now if we take a look at the generated SQL, we’ll see that ActiveRecord
correctly queried by our Chapters
table.
Although this won’t fix all problems with ActiveRecord, knowing is half the battle.