ブシトラの日記

エンジニア1年生の雑多記事

Railsガイド6.0読み直す ~6章 Active Record クエリインターフェイス

railsguides.jp

 

書いていく。読み応えがありそう

 

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 テーブルを結合する

結合は毎回よくわからなくなる

qiita.com

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 でテーブルの構造見れるのは便利ね