Railsガイド6.0読み直す ~6章 Active Record クエリインターフェイス
書いていく。読み応えがありそう
1 データベースからオブジェクトを取り出す
clients = Client.find([1, 10])
→ え、findって複数指定できるのかww 知らなかった
client = Client.take
→ ランダムでレコードを返す。知らなかった
clients = Client.take(2)
→ 引数に最大値とれるんかw
clients = Client.first(3)
→ firstも複数とれる
User.find_each(start: 2000,finish: 5000m, batch_size: 5000) do |user| NewsMailer.weekly(user).deliver_now end
→ User.all.each do だと、メモリ大量消費するからよくない、一旦Userで全部とったあとに処理するのがfind_each。レコードの件数指定も可能。startでキーを指定(例だとidが2000から処理開始)
find_in_batchesは バッチ を個別にではなくモデルの配列としてブロックにyieldするという点が違う。
バッチ処理のところは、慎重になろう
2 条件
以下の書き方は危険であり、避ける必要があります。→SQLインジェクション?
Client.where("orders_count = #{params[:orders]}")
3 並び順
4 特定のフィールドだけを取り出す
5 Limit と Offset
Client.limit(5).offset(30)
上のコードは、最初の30クライアントをスキップして31人目から最大5人のクライアントを返します。このときのSQLは以下のようになります。
直感的
6 グループ
groupもhavingも、あまりActiveRecord使うと意識しないよなー
7 Having
8 条件を上書きする
unscope → 特定の条件を取り除くことができます
only → 条件を上書きできます
reorder → デフォルトのスコープの並び順を上書きします
reverse_order → 並び順が指定されている場合に並び順を逆にします。
rewhere → 既存のwhere条件を上書きします
知らないのいっぱいあるな
9 Nullリレーション
noneメソッドは、チェイン (chain) 可能なリレーションを返します
→ チェーンさせる時に使うらしい
10 読み取り専用オブジェクト
client = Client.readonly.first
readonlyを使うことで変更不可になる
11 レコードを更新できないようにロックする
楽観的ロック (optimistic)
→ 複数のユーザーが同じレコードを編集することを許し、データの衝突が最小限であることを仮定しています
悲観的ロック (pessimistic)
→ データベースが提供するロック機構を使用します。リレーションの構築時にlockを使用すると、選択した行に対する排他的ロックを取得できます。
トランザクション内に処理書くやつ?
12 テーブルを結合する
結合は毎回よくわからなくなる
13 関連付けを一括読み込みする
N+1問題
14 スコープ
スコープをスコープ内でチェイン (chain) させることもできます。
class Article < ApplicationRecord scope :published, -> { where(published: true) } scope :published_and_commented, -> { published.where("comments_count > 0") } end
これ便利。
引数も渡せる。
default_scope { where(active: true) }
→ あんま使わんかもだけど、デフォルト設定もできる。ただ他のscopeより優先されるので注意
15 動的検索
16 Enums
17 メソッドチェインを理解する
18 新しいオブジェクトを検索またはビルドする
find_or_create_by
→ よく使う
find_or_initialize_by
→ インスタンスは生成されるが保存されない
19 SQLで検索する
pluckはまだ謎が深い
Client.select(:id).map { |c| c.id } # または Client.select(:id).map(&:id) # または Client.select(:id, :name).map { |c| [c.id, c.name] }
上は以下に置き換えられます。
Client.pluck(:id) # または Client.pluck(:id, :name)
20 オブジェクトの存在チェック
any?
empty?
many?
あたり
21 計算
sum
average
maximun
minimum
もあるのね
22 EXPLAINを実行する
User.joins(:posts).explain でテーブルの構造見れるのは便利ね