Slide 1

Slide 1 text

俺たちは雰囲気で scope をやっているけど もうちょっとなんとかならんのか? Reject on Rails 2024 Gotanda.rb 2024-10-17 tokai235

Slide 2

Slide 2 text

自己紹介 ● tokai235(トーカイ) です ● 現実世界ではギフティで働いています ○ 関西在住なのでこのオフィスでは「たまにいる人」です ● 実は Gotanda.rb 初参加、初登壇です ○ そんなことある? ○ やっていきます

Slide 3

Slide 3 text

Rails の scope 使ってますか?

Slide 4

Slide 4 text

scope とは ● Rails Guidesによると ○ よく使うクエリをスコープに設定すると、関連オブジェクトやモデルへのメソッ ド呼び出しとして参照できるようになります。 ○ ref: https://railsguides.jp/active_record_querying.html#スコープ こういうやつ (Rails Guides から抜粋)

Slide 5

Slide 5 text

もうちょっとわかりやすく ● SQL のパーツを Rails で書けるくんです ● 共通化や再利用ができるようになります

Slide 6

Slide 6 text

便利な scope ですが... こう思ったことないですか?

Slide 7

Slide 7 text

class method と 何が違うの?

Slide 8

Slide 8 text

そうなんすよ ● 実は↓の2つは同じ挙動をします ● シンプルな使い方をしている場合はどちらでも結果が同じ ○ これがむずい この2つは同じ挙動

Slide 9

Slide 9 text

じゃあ何が違うのか(定義編) ● ぶっちゃけこれに尽きます ● どのスコープメソッドも、常にActiveRecord::Relationオブジェクトを返しま す。 ● ref: https://railsguides.jp/active_record_querying.html#スコープ

Slide 10

Slide 10 text

どういうこと? ● scope で返していいのは SQL のパーツだけです ○ メソッドチェーンがつながらなくなるので ○ Rails Guides でも↓のように言っています ■ スコープの本体では、別のスコープなどのメソッドをスコープ上で呼び出せ るようにするため、ActiveRecord::Relation か nil のいずれかを返すように すべきです。 ■ ref: https://railsguides.jp/active_record_querying.html#スコープ ○ nil は何もしない扱いになります

Slide 11

Slide 11 text

たとえば ● こういうのはだめです ● pluck はただの array を返すので、その後の with_many_comments を解釈できずに エラーになります ● pluck(:id) は class method などで追加しましょう

Slide 12

Slide 12 text

じゃあ何が違うのか(実装編) ● scope の利点は scope で使えることです ○ 哲学ですね ● has_many で使えたり ● リレーション先のクエリで使えたり ● これらは class method ではできません ● データの取得を SQL に寄せることで、パフォー マンスやメモリ効率を良くすることができます ○ 大規模データの扱いは SQL が得意です ○ 事前の絞り込みで余計なインスタンスを作 らずに済みます

Slide 13

Slide 13 text

使ってよかった scope ● そもそも今回のテーマは筆者がパフォーマンス改善をした中で得た知見をまとめた ものです ● 何を改善したの? ○ 使える商品の一覧を金額でソートして取得する ○ これを SQL でなく Rails の class method や instance method で処理してま した ■ map とか filter とか ○ これに結構時間がかかってました

Slide 14

Slide 14 text

使ってよかった scope ● どうやったの? ○ map, filter などを scope に置き換 えて、SQL の時点でフィルタリング やソートがされるようにしました ● どうだった? ○ response time が 1/2 ~ 1/3 に改 善しました ■ 特に p99th が良好 ○ 詳細知りたい方はビール飲みながら お話しましょう

Slide 15

Slide 15 text

まとめ ● scope は SQL のパーツを Rails で書けるくんです ○ おかげで SQL の共通化や再利用ができます ○ 組み合わせると柔軟に SQL クエリが書けます ● scope を使うときは SQL のパーツを返すようにしましょう ○ メソッドチェーンがつながるように ● データの取得を適切に SQL でハンドリングすることで、パフォーマンスやメモリ 効率をよくできます

Slide 16

Slide 16 text

scope やっていきましょう💪