Rails Active Record Query
I have used LINQ in C# quite a while ago. The LINQ interface is quite user friendly, and I could write simple queries after seeing a few examples. At
that time, I was quite ignorant of the N+1
problem, so I was not sure if I introduced any in the queries I composed.
The counterpart of LINQ in Rails world is active record, but I have never found it as smooth as LINQ, and I find myself always instantiating arrays
way too often. Non-surprisingly, some pages on the website are quite slow. Decided to take this seriously, and really learn this active record stuff
in Rails, I followed http://www.theodinproject.com/ruby-on-rails/active-record-queries and used ActiveRecord::QueryMethods
on
http://api.rubyonrails.org as the reference.
Rewriting two methods using the knowledge I acquired introduced 20x speedup for some queries, so it’s worth learning it in depth. I shall note down my understanding, which might be of some use for others.
1 | Model.joins(:association).where("table_name.column" => value) |
An potentially puzzling part could be the two namespace, active record models, and database tables. Inside joins
, we are using the active record
models, so that Model
has a association called “association”, while inside where
, we are using database namespace, so that the above example
assumes that there’s a table called “table_name” with a column named “column”.
Another common confusion is between include
and joins
, and here’s my interpretation: include
is used for eager loading so that late access of
the association would not result into extra SQL queries, while joins
is used for bringing other models into the namespace, so that following clauses
(e.g. where
) could reference them. In certain cases, one may want to do both, then:
1 | Model.includes(:association).where("table_name.column" => value).references(:association) |