はじめに仕込んでいたgem bulletが警告ログを発したので解決してみます。
##N + 1問題とは?
データベースへのアクセス回数が必要以上に多くなってしまう現象の事。モデル間のアソシエーションで発生します。
##gem bulletとは?
N + 1問題が発生してる箇所を警告で教えてくれるgemです。
##現状
CareRecipitent Load (0.4ms) SELECT "care_recipitents".* FROM "care_recipitents"
↳ app/views/caregiver/tops/index.html.erb:1
Caregiver Load (0.5ms) SELECT "caregivers".* FROM "caregivers" WHERE "caregivers"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
↳ app/views/caregiver/tops/index.html.erb:37
CACHE Caregiver Load (0.0ms) SELECT "caregivers".* FROM "caregivers" WHERE "caregivers"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
↳ app/views/caregiver/tops/index.html.erb:37
CACHE Caregiver Load (0.0ms) SELECT "caregivers".* FROM "caregivers" WHERE "caregivers"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
↳ app/views/caregiver/tops/index.html.erb:37
Rendered caregiver/tops/index.html.erb within layouts/caregiver (Duration: 16.2ms | Allocations: 6553)
CACHE Caregiver Load (0.1ms) SELECT "caregivers".* FROM "caregivers" WHERE "caregivers"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
はじめに親モデルに検索がかけられ、その後に子モデルに4回クエリが発行されていることがわかります。
##解決策
子モデル.includes(:親モデル)
def index
#@caregiver = Caregiver.find(params[:staff_member_id])
- @care_recipitents = CareRecipitent.all
+ @care_recipitents = CareRecipitent.includes(:caregiver)
end
コントローラーのindexアクションを書き換えます。
CareRecipitent Load (1.2ms) SELECT "care_recipitents".* FROM "care_recipitents"
↳ app/views/caregiver/tops/index.html.erb:1
Caregiver Load (0.6ms) SELECT "caregivers".* FROM "caregivers" WHERE "caregivers"."id" = $1 [["id", 1]]
↳ app/views/caregiver/tops/index.html.erb:1
Rendered caregiver/tops/index.html.erb within layouts/caregiver (Duration: 75.3ms | Allocations: 19989)
Caregiver Load (0.3ms) SELECT "caregivers".* FROM "caregivers" WHERE "caregivers"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
クエリの回数が減り、無事ログを消えました。