Slide 1

Slide 1 text

© 2023 Wantedly, Inc. N+1 問題の解決と computed_model Oct. 5 2023 - Ryota Egusa (@gedorinku)

Slide 2

Slide 2 text

Wantedly のアーキテクチャ © 2023 Wantedly, Inc. Rails のマイクロサービス GraphQL のデータソースなどに使われる、汎用 的な API を持つ

Slide 3

Slide 3 text

加工した値を返すモデルのメソッド class User < ApplicationRecord has_many :work_experiences # => "ウォンテッドリー株式会社 / エンジニア" def position_description work_experience = work_experiences.max_by { _1.started_at } "#{work_experience.company_name} / #{work_experience.position}" end end © 2023 Wantedly, Inc.

Slide 4

Slide 4 text

Preload と N+1 問題 class User < ApplicationRecord has_many :work_experiences … end User.where(...).map(&:position_description) User.preload(:work_experiences).where(...).map(&:position_description) © 2023 Wantedly, Inc.

Slide 5

Slide 5 text

computed_model による解決方法 class User define_primary_loader :raw_user do ... end define_loader :work_experiences do ... end dependency :work_experiences computed def position_description work_experience = work_experiences.max_by { _1.started_at } "#{work_experience.company_name} / #{work_experience.position}" end end © 2023 Wantedly, Inc. 依存関係をここに書く ここに書かれていないものを使うと エラーになる

Slide 6

Slide 6 text

Active Record をデータソースとして使う例 class User define_primary_loader :raw_user do |_, ids:, **| RawUser.where(id: ids).map do |raw_user| User.new(raw_user) end end define_loader :work_experiences do ... end end © 2023 Wantedly, Inc.

Slide 7

Slide 7 text

他サービスの API をデータソースとして使う例 class User define_primary_loader :raw_user do ... end define_loader :work_experiences, key: -> { id } do |user_ids, _, **| WorkExperienceApiClient.list(user_ids: user_ids).group_by(&:user_id) end end © 2023 Wantedly, Inc.

Slide 8

Slide 8 text

computed_model からデータを読む 指定していないフィールドを使うとエラーになる users = User.batch_get(user_ids, [:position_description]) users.map(&:position_description) users.map(&:name) # => error © 2023 Wantedly, Inc.

Slide 9

Slide 9 text

まとめ 1. 抽象化を損なわず依存関係解決 ○ N+1問題を防ぎ、必要なデータだけ読み込む 2. データソースには Active Record に限らず HTTP API なども使える © 2023 Wantedly, Inc. https://github.com/wantedly/computed_model