前提
ブログとカテゴリがn:nの関係
app/models/blog.rb
class Blog < ApplicationRecord
has_many :blogs_categories
has_many :categories, through: :blogs_categories, source: :category
end
app/models/category.rb
class Category < ApplicationRecord
has_many :blogs_categories
has_many :blogs, through: :blogs_categories, source: :blog
end
app/models/blogs_category.rb
class BlogsCategory < ApplicationRecord
belongs_to :blog
belongs_to :category
end
ちなみに中間テーブルの名前は 複数_複数
とするのがRailsのルール。
今回なら blogs_categoriesテーブル
。
ちなみにモデル名は 複数_単数
とするみたい。
今回なら ファイル名が blogs_category.rb
クラス名が BlogsCategory
。
ややこしや。。
includesのみ
アソシエーションごとにキャッシュ
今回は以下3つのテーブルがあるので
- blogsテーブル
- blogs_categoriesテーブル
- categoriesテーブル
クエリは3回
app/controllers/blogs_controller.rb
class BlogsController < ApplicationController
def index
@blogs = Blog.includes(:categories)
end
# 省略
end
Blog Load (0.7ms) SELECT "blogs".* FROM "blogs"
BlogsCategory Load (0.9ms) SELECT "blogs_categories".* FROM "blogs_categories" WHERE "blogs_categories"."blog_id" IN (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
Category Load (0.3ms) SELECT "categories".* FROM "categories" WHERE "categories"."id" IN (1, 2, 3, 4, 5)
includes + references
LEFT OUTER JOINで1回のクエリでアソシエーションをキャッシュ
app/controllers/blogs_controller.rb
class BlogsController < ApplicationController
def index
@blogs = Blog.includes(:categories).references(:all)
end
# 省略
end
SELECT "blogs"."id" AS t0_r0,
"blogs"."title" AS t0_r1,
"blogs"."content" AS t0_r2,
"blogs"."deleted_at" AS t0_r4,
"blogs"."created_at" AS t0_r5,
"blogs"."updated_at" AS t0_r6,
"blogs"."publish_at" AS t0_r7,
"blogs"."status" AS t0_r9,
"categories"."id" AS t1_r0,
"categories"."name" AS t1_r1,
"categories"."created_at" AS t1_r3,
"categories"."updated_at" AS t1_r4,
FROM "blogs"
LEFT OUTER JOIN "blogs_categories"
ON "blogs_categories"."blog_id" = "blogs"."id"
LEFT OUTER JOIN "categories"
ON "categories"."id" = "blogs_categories"."category_id"