find,find_by,whereの戻り値の違い
- find
- ActiveRecord::RecordNotFound例外
- find_by
- nil
- where
- 空のActiveRecord::Relationインスタンス
ActiveRecord::Relationについて
- ActiveRecord(モデル)に対してQueryInterface(select,where,etc)が呼ばれることでActiveRecord::Relationのインスタンスが作成される
- ActiveRecord::Relationインスタンスに対してQueryInterfaceを繰り返し呼び出せる
- 実際にデータが必要になった時点でSQLが発行され、それまではActiveRecord::RelationにSQLの情報が蓄積される。
- ただし、
to_a
メソッドにより、明示的にSQLを発行することもできる。
scopeについて
- スコープとは?
- よく使う検索条件に名前をつけて再利用しやすくする仕組み
- スコープの戻り値
- 必ずActiveRecord::Relationを返す
- なので、scope定義でfind_by(nilを返す)を使うと、一件も取得できない時に、find_byの条件を無視して、全件取得してきちゃう。
- **なので!、**scope定義ではfind_byは使わない方がいい(合ってますか?)
- 参考→【Rails】スコープでfind_byを使用して、条件に一致するレコードがないとnilではなくレコード全件が返される理由 #Ruby - Qiita
モデル間のリレーションについて
- リレーション作成の流れ
- 条件
- 1対多(Group(多)、Member(1))
-
Memberに外部キーを追加する
rails generate migration AddGroupIdToMembers group:references
これにより、membersテーブルに、group_idが追加される
-
Group、Memberモデルに関連を宣言する
class Group < ApplicationRecord has_many :member end class Member < ApplicationRecord belongs_to :groups end
- 条件
ActiveRecord::Enumについて
-
ActiveRecord::Enumとは?
- ステータスを管理するカラム(例:値が、0, 1, 2に限られる)をRailsで扱いやすくするために、対応した名称でアクセスできるようにしてくれる機能
-
例
- Todoモデルのステータス(0:waiting、1:working、2:completed)を名前で管理、更新する
class Todo < ApplicationRecord enum todo_status: { waiting: 0, working: 1, completed: 2, } # 略 end
こうすることで、Todoの更新、作成の時に名称(文字列orシンボル)もしくは数値で指定できる。
Todo.create(todo_status: "waiting") Todo.create(todo_status: :waiting) Todo.create(todo_status: 0) # 全て同じ結果になる。
また、述語メソッドで問い合わせも可能になる。
todo = Todo.first todo.waiting? # false todo.waiting! # 変更できる todo.waiting? # true
ステータスの一覧(名称と実際の値のハッシュ)や、実際の値にアクセスできる
Todo.todo_statuses # => {"waiting"=>0, "working"=>1, "completed"=>2} todo.todo_status_before_type_cast # => 0
スコープも追加される
Book.waiting # => ステータスがwaitingのものを検索 Book.not_waiting # => ステータスがwaitingでないものを検索