Lugo Labs

Know your ActiveRecord objects

I don't know about you, but sometimes I find it difficult to escape the SQL mindset and think of models as objects. Probably because the performance is always at the back of my mind, and I sometime don't trust ActiveRecord to produce the most optimised query. These fears are not founded though, they're mostly based on not checking the SQL produced.

Let's say that we have two models: Book and Author and their relationship is a book has many authors. So in our 'Book' model we have:

ruby
# app/models/book.rb

class Book < ActiveRecord::Base
  has_many :authors
end

For some reason we want to add an author to a book, so we write the following statements:

ruby
book = Book.find(book_id)
Author.create!(name: 'Dan Brown', book: book)

Pretty ingenious, right? That's our SQL hat right there. A better statement would be:

ruby
book = Book.find(book_id)
book.authors.create!(name: 'Dan Brown')

Thus we take advantages of the methods added by ActiveRecord through has_many macro.

The same is valid for queries:

ruby
book = Book.find(book_id)
author = Author.find_by(name: 'Dan Brown', book_id: book.id)

Naturally a better statement would be:

ruby
book = Book.find(book_id)
author = book.authors.find_by(name: 'Dan Brown')

ActiveRecord takes care of scoping the authors on their book, and helps to think more in terms of objects, rather than SQL.