テクノロジー

2016年11月05日

ActiveRecord02

Aws4 request&x amz signedheaders=host&x amz signature=2413d0f890bad34cfea74a5b4e2a246993c60015bc2a91656913646082882af9

AcitveRecordの保存・削除系メソッドとは

さて前回は、DBからレコードを取得するActiveRecordの「取得系」メソッドについて触れていきました。
今回はDBにあるレコードを更新したり削除したりするActiveRecordの「保存/削除系」について徹底分析していきます。
前回と同様、Railsコンソールを用いて実際に手を動かしながら一緒に確認しましょう。

主な「保存/削除系」メソッド

saveメソッド

これは変数に入っているモデルのインスタンスをDBに保存するメソッドです。
使い方としては以下のように何らかの変数にインスタンスを入れてsaveメソッドを実行します。

@blog = Blog.new(title: 'aaaaa', content: 'bbbbb')
@blog.save

なお、以下のようにモデルのクラスに直接saveメソッドは実行できません。

Blog.save

saveメソッドを実行すると以下のようにSQLが走り、DBにレコードが保存されます。

(51.9ms)  BEGIN
  SQL (80.9ms)  INSERT INTO "blogs" ("title", "content", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id"  [["title", "aaaaa"], ["content", "bbbbb"], ["created_at", 2016-10-28 08:18:09 UTC], ["updated_at", 2016-10-28 08:18:09 UTC]]
(18.3ms)  COMMIT
=> true

VALUESの$1はRETURNINGの右側に書いてある[“title”, “aaaaa”]をさしています。$2以下もcontent, created_atのように続きます。先頭のidは自動で設定されるものです。
saveメソッドで返る値は真偽値(trueかfalse)なのでチェックしておきましょう。

created_blog = @blog.save <= 変数にblogが入りそうなイメージをするかもしれませんが中身を確認すると...
created_blog => trueが返る

updateメソッド

これは既存のレコードを取り出して値を書き換えたあとにDBに保存するメソッドです。書き方は2つあります。
まずは先ほどのsaveメソッドのように何らかの変数に既存のレコードを代入して書き換える方法です。

@blog = Blog.find(3)
@blog.update(title: 'ddddd')

2つ目は先ほどできなかったモデルのクラスに直接updateメソッドを実行する方法です。
IDと書き換えるキー・値を引数にとってメソッドを実行します。

Blog.update(3, title: 'ddddd')

updateメソッドを実行させると以下のようにSQLが走り、DBにあるレコードが更新されます。

(0.2ms)  BEGIN
  SQL (0.5ms)  UPDATE "blogs" SET "title" = $1, "updated_at" = $2 WHERE "blogs"."id" = $3  [["title", "ddddd"], ["updated_at", 2016-10-28 08:38:34 UTC], ["id", 3]]
(6.6ms)  COMMIT

destroyメソッド

これは既存のレコードをDBから削除するメソッドです。こちらも書き方は2つあります。
まずは何らかの変数に既存のレコードを代入してDBから該当のレコードを削除する方法です。

@blog = Blog.find(3)
@blog.destroy

一方でモデルのクラスに直接メソッドを実行することもできます。その時はIDを引数にとって、どのレコードを削除するのかを指定します。

 Blog.destroy(1)

さらに以下のようにIDを複数指定すれば、複数のレコードをまとめて削除することもできます。

Blog.destroy([1, 3])

destroyメソッドを実行すると以下のようにSQLが走り、DBから対象のレコードが削除されます。

Blog Load (0.5ms)  SELECT  "blogs".* FROM "blogs" WHERE "blogs"."id" = $1 LIMIT $2  [["id", 11], ["LIMIT", 1]]
   (0.3ms)  BEGIN
  SQL (0.3ms)  DELETE FROM "blogs" WHERE "blogs"."id" = $1  [["id", 11]]
   (6.1ms)  COMMIT
=> #<Blog:0x007fec85647430
 id: 1,
 title: "aaaaa",
 content: "ccccc",
 created_at: Fri, 28 Oct 2016 13:07:22 UTC +00:00,
 updated_at: Fri, 28 Oct 2016 13:07:22 UTC +00:00>

destroy_allメソッド

これはDBから全てのレコードを一気に削除したいときに使うメソッドです。

Blog.destroy_all

一方で、条件に該当したレコードを一気に削除する方法もあります。それはwhereメソッドとの組み合わせで実現できます。
例えばtitleが「aaaaa」のレコードを全て削除する場合は以下のように記述することができます。

Blog.where(title: 'aaaaa').destroy_all

destroy_allメソッドを実行すると以下のように、まずSELECT文が走ります。

Blog Load (1.0ms)  SELECT "blogs".* FROM "blogs"
   (0.2ms)  BEGIN
  SQL (0.4ms)  DELETE FROM "blogs" WHERE "blogs"."id" = $1  [["id", 12]]
   (6.3ms)  COMMIT
   (0.3ms)  BEGIN
  SQL (0.5ms)  DELETE FROM "blogs" WHERE "blogs"."id" = $1  [["id", 13]]
   (5.7ms)  COMMIT
   (0.2ms)  BEGIN
=> [#<Blog:0x007fec852a7d70
  id: 12,
  title: "aaaaa",
  content: "ccccc",
  created_at: Fri, 28 Oct 2016 13:09:07 UTC +00:00,
  updated_at: Fri, 28 Oct 2016 13:09:07 UTC +00:00>,
 #<Blog:0x007fec852a7b68
  id: 13,
  title: "aaaaa",
  content: "ccccc",
  created_at: Fri, 28 Oct 2016 13:09:08 UTC +00:00,
  updated_at: Fri, 28 Oct 2016 13:09:08 UTC +00:00>]

これは前回の取得系で取り上げたallメソッドの時と同じSQLです。続いてDELETE文が走っているのが確認できます。
これでDBから全てのレコードを削除することができます。

いかがでしたでしょうか。これらのメソッドは開発していたら頻繁に出てくるので、実際にコンソールで動かしてみてどんなメソッドかを把握しておきましょう。

DIVE INTO CODEのことをもっと知ってみませんか?