後へ      Topへ      次へ

データベースの操作

Rails のモデルを通して、データベースを操作する方法について、
基本的なものを挙げておきます。

find, find_by_id

指定モデルの指定IDのレコード1つを取得するメソッドです。
@book = Book.find(1) なら、
books テーブルから、ID:1 のレコードデータを @book に返します。
指定ID のデータが見つからなければ例外を吐きます。

find の代わりに find_by_id を使えば、
指定ID のデータが見つからなければ nil を返します。

find_by

指定モデルの指定カラムのレコード1つを取得するメソッドです。
@book = Book.find_by(name: "こころ") なら、
books テーブルから、name カラムの値が “こころ” のレコードデータ1つを @book に返します。
指定のデータが見つからなければ nil を返します。

該当条件のデータが複数ある場合でも、
実際に取得できるデータは1つで、
どれが返されるかはデータベースの状態によって変わります。
確定させるには、
後述の where, order などを使ってください。

 

where, or

指定モデルの指定条件カラム(複数可)のレコードを取得するメソッドです。
SQL の WHERE の働き。
条件に合致するデータ全てを ActiveRecord::Relation 型で返します。
@books = Book.where(name: "こころ") なら、
books テーブルから、name カラムの値が “こころ” のレコードデータ全てを @books に返します。

条件を複数指定した場合は AND になります。
@data = Cabinet.where(name: "C1-100", floor_id: 1) なら、
cabinets テーブルから、name が “C1-100” かつ floor_id が 1 のレコードデータ全て。

1つのカラム内で複数指定したい場合は、配列で記載します。
@data = Cabinet.where(name: ["C1-100", "C1-101"] ) なら、
name が “C1-100” または “C1-101” のレコードデータ全て。

.or も使えます。
@data = Cabinet.where(name: "C1-100").or(Cabinet.where(floor_id: 1)) なら、
name が “C1-100” または floor_id が 1 のレコードデータ全て。

.or の左右はスコープを揃える必要があります。

例えば、
Book.where(category_id: 1).where(name: ["こころ1", "白夜行"])
を .or を使って書こうとしたら、
Book.where(category_id: 1).where(name: "こころ1").or(Book.where(category_id: 1).where(name: "白夜行"))
のように、左右両方に where(category_id: 1) が必要です。

そうじゃなくて、
Book.where(category_id: 1).where(name: "こころ1").or(Book.where(name: "白夜行"))
と書いてしまうと、
Book.where(category_id: 1).where(name: "こころ1")
と
Book.where(name: "白夜行")
を足したものになり、前者とは違う結果になります。

スコープを気にしないといけない場面では、
・同じカラムに対してなら where(name: ["C1-100", "C1-101"] ) のように配列で、
・異なるカラムに対してなら where("name=? OR floor_id=?", "C1-100", 1) のようにSQL形式で、
それぞれ書いたほうが無難かもしれません。

 

select

データベースから取り出してくるカラムを限定します。
SQL の SELECT の働き。
@data = Book.select(:id, :name) なら、
books テーブルから、id と name カラムのみを取り出します。
扱うデータ量を減らす効果があります。

[#<Book:0x000002a1815928e0 id: 1, name: "こころ">,
 #<Book:0x000002a18343d2b8 id: 2, name: "人間失格">,
 ・・・続く
]
のようなデータを返します。

 

order

データをソートします。
SQL の ORDER BY の働き。

@data = Cabinet.order(:name) とすると、
name を昇順でソートした結果を返します。

@data = Cabinet.order(name: "desc") とすると、
name を降順でソートした結果を返します。
(カラム名に対してコロンを付ける場所に注意)

ソートは、多段階も可能です。
@data = Step.order(:cabinet_id, name: "desc") とすると、
まず cabinet_id を昇順でソートし、
次に同じ cabinet_id の中で name を降順でソートします。

new

新しいデータを用意します。

@book = Book.new とすると、
各カラムの値がデフォルト値のデータが @book に格納されます。

@book = Book.new(name: "新刊") などとすると、
引数に指定した部分だけ値が格納された (&その他はデフォルト値の) データになります。

このメソッドは、コード的にデータを用意するだけなので、
後述の save などを使ってデータベースに保存しないといけません。

save

データをデータベースに保存します。
(新規データを保存する際に使用)
成功すると true、失敗すると false を返します。
errors でエラー内容が取得できます。

flag = @book.save
mes = @book.errors

save! なら、失敗時に例外を吐きます。

update

データをデータベースに保存します。
(既存データを更新する際に使用)
成功すると true、失敗すると false を返します。
errors でエラー内容が取得できます。

update! なら、失敗時に例外を吐きます。

destroy

指定のデータをデータベースから削除します。
destroy! なら、失敗時に例外を吐きます。

pluck

指定したカラムを抽出し、配列の配列で返します。

データベースの logs データが
#<Log: id: 3, book_id: 3, status: 1,  user_id: 1, (他略)>
#<Log: id: 4, book_id: 4, status: 2,  user_id: 1, (他略)>
の時、
Log.pluck(:book_id, :status)
の返り値は
[[3, 1], [4, 2]]
になります。

使い方は select と似ていますが、
こちらは配列を返すので、
モデル・メソッドのチェーンを後に続けることができない点に注意です。

Log.pluck(:book_id, :status).order(:book_id)
とかはエラーになります。

後へ      Topへ      次へ