For example the original associations:
class Category < ActiveRecord::Base has_many :foods end class Food < ActiveRecord::Base belongs_to :category endand eager loading (aka preloading) the categories and their associated foods:
@categories = Category.includes(:foods).allgenerates a SQL like:
SELECT "categories".* FROM "categories" SELECT "foods".* FROM "foods" WHERE "foods"."category_id" IN (1, 2, 3)Please note that ActiveRecord::QueryMethods#includes generates 2 SQL queries. The database tables categories and foods are not joined together.
And that is exactly the same what ActiveRecord::QueryMethods#preload does. That is why:
@categories = Category.preload(:foods).allalso generates the SQL:
SELECT "categories".* FROM "categories" SELECT "foods".* FROM "foods" WHERE "foods"."category_id" IN (1, 2, 3)But beware, the selection conditions are not allowed to refer to the preloaded association table attributes.
So something like:
@categories = Category.preload(:foods).where("foods.name LIKE '%corn%'").allwill raise an SQL exception:
SQLException: no such column: foods.name: SELECT "categories".* FROM "categories" WHERE (foods.name LIKE '%corn%')But as long as the query is simple and is intended to keep on being simple, it totally makes sense to prefer ActiveRecord::QueryMethods#preload to ActiveRecord::QueryMethods#includes.
Furthermore it is more intentional about what the code is doing. And that is always a win.
Further articles of interest:
Supported by Ruby 2.1.1 and Ruby on Rails 3.2.17
Keine Kommentare:
Kommentar veröffentlichen