In the previous post I covered Migrations, Validations and Callbacks. In this post I will be covering Associations and Query Interface guides.
It’s normal for an association to work in two directions. For example, an article has_many comments and a comment belongs_to an article. By default, Active Record doesn’t know about the connection between these associations. This can lead to two copies of an object getting out of sync. To prevent this use inverse_of.
If you are using Rails 4.1+ you probably don’t have to worry about this. Rails will automatically detect inverse associations using simple heuristics. For complex associations, you will have to define them yourself.
Often, in has_many association, you need to cache number of belonging objects. For example, if you are building a blog application and displaying a list of articles on the home page, you would often need to display count of comments on each article. To avoid extra db calls, you would store the number of comments in article itself and update it every time a comment is added or removed from the article. Active Record provides counter_cache option on belongs_to association, which will simplify this for you.
dependent - restrict_with_exception and restrict_with_error
dependent option determines what happens to associated objects when the owner is destroyed. The two most popular options are
:delete. Almost every Rails tutorials mentions these options. But often you would want to prevent the owner from getting destroyed if there are any associated objects.
:restrict_with_error serve this purpose. The former raises an exception, while the latter adds a validation error to the owner object.
When are Objects Saved?
There are certain nuances regarding when objects are saved when assigned to an association. Rails guide does very well to explain this for belongs_to, has_one, has_many and has_and_belongs_to_many associations.
In addition to normal callbacks, Active Record also provides callbacks that are triggered by association events such as, adding/removing objects from an association. There are four association callbacks available.
find_each and find_in_batches
Many times you need to fetch large number of records from database and iterate over them. It’s not efficient to fetch a large number of records in one go. You might not even have enough memory to hold all the objects in memory. Rails provides two methods
find_in_batches that fetch records in batches. The detailed explanation could be found in Rails Guides.
Nested hash conditions
Ever wanted to perform query on attributes of associated objects and ended up writing it like this:
I had been doing this simply because I didn’t know I could use nested hash like this:
I used to write NOT SQL queries by passing sql string to where:
With Rails 4.0, this can be done by using
It’s not just cleaner; It provides some additional features too.
Sometimes you need to remove/override conditions from an already built query. One example of this would be using
unscoped to remove the default scope. Active Record provides 5 more methods for this purpose:
Active Record provides
none method which returns an empty
ActiveRecord::Relation object without firing any database queries. Use case for this is well illustrated in the Rails Guides
find_or_create_by often you would want to set some attributes for the new record but you don’t want to include them in the query. One way to achieve this is by passing a block to
find_or_create_by and setting attributes inside the block. Active Record provides a method, create_with to do the same.
With this, I have covered Rails Guides related to Active Record. In the next article I will explore views and controllers.