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
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.
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
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
where) could reference them. In certain cases, one may want to do both, then:
Model.includes(:association).where("table_name.column" => value).references(:association)