【Rails】コンソールからモデルを使ってテーブルの一覧表示やデータ追加・更新・変更・削除する方法(データベース操作)

rails-prograshi(プロぐらし)-kv Rails
記事内に広告が含まれていることがあります。

Railsのモデルを使うと、データベースに直接アクセスせずに、Rails経由でデータベースの操作を行うことができます。

データベースがMySQLやPostgreSQLに関わらず同じコマンドでデータベースを操作できるのでとても簡単です。

Railsの対話モードに入る

Railsからテーブル操作を行うには、対話モードに入る必要があります。

rails c コマンドを実行します。(rails console の略です。どちらのコマンドでも対話モードに入れます)

# rails c
Running via Spring preloader in process 197
Loading development environment (Rails 6.1.4)
irb(main):001:0>


irbとは

Railsの対話モードに入るとirbという文字が表示されます。

irbとは、InteractiveRubyの略で、Rubyの対話モードという意味です。

001:0は、全体の行数:現在のコードの行数 を表しています。

  • 全体の行数: 改行する毎に1づつ増える。
  • 現在のコードの行数: if文など処理が終了せずに続いている場合に改行すると1づつ増える。(処理が完了すると、0に戻る)
終了するには?

Railsの対話モードから抜けるには exit を入力します。

Docker上のRailsの場合

Docker上のRailsを使っている場合は、Railsコンテナに入ってから、対話モードに入る必要があります。

Railsコンテナが起動中である必要があります。

#起動中のコンテナ一覧を確認
docker ps

#Railsコンテナに入る
$ docker exec -it <コンテナ名> bash

#対話モードに入る
root@d90f784d2e64:/rails-vue# rails c
Running via Spring preloader in process 229
Loading development environment (Rails 6.1.4)
irb(main):001:0>


モデル経由でのテーブル操作の注意点

モデル経由でテーブルを操作できるのは、テーブルや中身の表示、一部のデータの追加・変更・削除です。

テーブルにカラムを追加したり、カラムを削除するといった、スキーマ自体の変更はマイグレーションファイル経由で行う必要があります。

また、スキーマの変更内容をRailsの対話モードに反映する場合は、一度コンテナから出て、再度コンテナに入り直す必要があります。

#対話モードから抜ける
irb(main):004:0> exit

#コンテナから抜ける
root@a3d49a8a5adf:/rails-vue# exit
exit

#コンテナに入る
docker exec -it <コンテナ名> bash


カラムを追加するマイグレーションファイルの作成方法

次のコマンドを実行すると、カラムを追加するためのマイグレーションファイルを生成してくれます。

rails g migration Add<カラム名>To<モデル名> <カラム名1:型1> <カラム名2:型2>,,, 

カラムを削除するマイグレーションファイルの作成方法

次のコマンドを実行すると、カラムを追加するためのマイグレーションファイルを生成してくれます。

rails g migration Remove<カラム名>To<モデル名> <カラム名1:型1> <カラム名2:型2>,,, 

他にもカラムを追加したり、ユニークの設定をつける場合は、生成したマイグレーションファイルを直接編集します。

編集後に、rails db:migrateを実行します。

スキーマを変更した後は、 Railsの対話モードに反映する場合は、一度コンテナから出て再度コンテナに入り直す必要があります。



テーブル一覧の表示

テーブルの一覧を表示するには、ActiveRecord::Base.connection.tables を実行します

irb(main):001:0> ActiveRecord::Base.connection.tables
=> ["schema_migrations", "ar_internal_metadata", "clients", "active_admin_comments", "tests"]


上記の例だと、次の5つのテーブルが存在していることがわかります。

  1. schema_migrations
  2. ar_internal_metadata
  3. clients
  4. active_admin_comments
  5. tests
デフォルトで存在するテーブル

(1)schema_migrationsと、(2)ar_internal_metadataはRailsのDB操作に必要となるデフォルトで用意されているテーブルです。

これらは基本的に操作、編集、削除等する必要がありません。

  • schema_migrations: マイグレーションのバージョン(実行履歴)を保存
  • ar_internal_metadata: 間違ってDBを削除するのを防ぐためのテーブル


テーブルのカラム一覧を表示する

テーブルの中にどんなカラムが入っているかを確認したい場合は次のコードを実行します。

検索結果は配列です。

モデル名.column_names
テーブル名とモデル名の対応

テーブル名とモデル名には命名規則があります。このため、どちらかがわかれば、もう一方もわかります。

項目命名規則詳細
テーブルスネークケース複数形全て小文字の複数形
モデルアッパーキャメルケース単数形単語の冒頭が大文字の単数形

テーブル名とモデル名の

テーブル名モデル名モデルファイル名
clientsClientclient.rb
client_numbersClientNumberclient_number.rb

実例

#テーブル一覧を表示
irb(main):001:0> ActiveRecord::Base.connection.tables
=> ["schema_migrations", "ar_internal_metadata", "clients", "active_admin_comments", "tests"]

#clientsテーブルのカラム一覧を表示
irb(main):003:0> Client.column_names
=> ["id", "pj_name", "client_name", "status", "order_date", "price", "memo", "created_at", "updated_at"]

clientsテーブルのカラム一覧を確認したいので、モデル名はClientになります。


テーブルの中身を確認する

テーブルの中身を確認する方法は大きく3つあります。

  1. すべて表示(all)
  2. id番号で指定(find)
  3. カラムとデータを指定(find_by)
  4. 番号をアルファベットで指定 (first,,,fifth, last)
  5. 条件で絞り込み(where)

すべて表示(all)

テーブルの中の全てのデータを見たい場合はallメソッドを使います。検索結果はActiveRecord::Relationのインスタンスです。

モデル名.all
tips
  • 検索結果は、改行なしで表示されます。#< が新しい行の始まりです。
  • データが存在しない場合は、#<ActiveRecord::Relation []> が返ります。
  • 検索結果はActiveRecord::Relationのインスタンスです。
ActiveRecord::Relationとは?

Railsのテーブル操作で結果として返ってくる型には、主に次の3つがあります。

  • 配列
  • オブジェクト
  • ActiveRecord::Relation


ActiveRecord::Relationはモデルを使ってSQLクエリを実行できる型です。

このため、.allで取得した結果に、.findなどのテーブルを操作するメソッドをつなげることができます。

irb(main):074:0> Test.all.find(9)
  Test Load (0.7ms)  SELECT "tests".* FROM "tests" WHERE "tests"."id" = $1 LIMIT $2  [["id", 9], ["LIMIT", 1]]
=> #<Test id: 9, name: "ユーザー2", created_at: "2021-07-20 00:30:31.939292000 +0000", updated_at: "2021-07-20 00:30:31.939292000 +0000">

実例

#データが空の場合
irb(main):031:0> Test.all
  Test Load (0.6ms)  SELECT "tests".* FROM "tests" /* loading for inspect */ LIMIT $1  [["LIMIT", 11]]
=> #<ActiveRecord::Relation []>


#データが複数存在する場合
irb(main):032:0> Test.all
  Test Load (0.7ms)  SELECT "tests".* FROM "tests" /* loading for inspect */ LIMIT $1  [["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<Test id: 8, name: "ユーザー1", created_at: "2021-07-20 00:30:22.334075000 +0000", updated_at: "2021-07-20 00:30:22.334075000 +0000">, #<Test id: 9, name: "ユーザー2", created_at: "2021-07-20 00:30:31.939292000 +0000", updated_at: "2021-07-20 00:30:31.939292000 +0000">, #<Test id: 10, name: "ユーザー3", created_at: "2021-07-20 00:30:42.764326000 +0000", updated_at: "2021-07-20 00:30:42.764326000 +0000">]>


id番号で指定(find)

id番号で指定したデータを取得することもできます。

モデル名.find(id番号)


id番号は複数指定することもできます。

モデル名.find(id1, id2, id3,,,)
複数指定の場合
  • 複数のデータを検索したい場合は、idを使うと存在しない場合にエラーになります。
  • whereを使う方がお勧めです。
  • 結果はオブジェクトが返ります。

実例

#id番号9を検索
irb(main):035:0> Test.find(9)
  Test Load (0.5ms)  SELECT "tests".* FROM "tests" WHERE "tests"."id" = $1 LIMIT $2  [["id", 9], ["LIMIT", 1]]
=> #<Test id: 9, name: "ユーザー2", created_at: "2021-07-20 00:30:31.939292000 +0000", updated_at: "2021-07-20 00:30:31.939292000 +0000">


#複数検索 8,9,10
irb(main):036:0> Test.find(8,9,10)
  Test Load (0.9ms)  SELECT "tests".* FROM "tests" WHERE "tests"."id" IN ($1, $2, $3)  [["id", 8], ["id", 9], ["id", 10]]
=> [#<Test id: 8, name: "ユーザー1", created_at: "2021-07-20 00:30:22.334075000 +0000", updated_at: "2021-07-20 00:30:22.334075000 +0000">, #<Test id: 9, name: "ユーザー2", created_at: "2021-07-20 00:30:31.939292000 +0000", updated_at: "2021-07-20 00:30:31.939292000 +0000">, #<Test id: 10, name: "ユーザー3", created_at: "2021-07-20 00:30:42.764326000 +0000", updated_at: "2021-07-20 00:30:42.764326000 +0000">]



▼指定したIDが存在しない場合

#idが存在しない場合
irb(main):037:0> Test.find(1)
  Test Load (0.8ms)  SELECT "tests".* FROM "tests" WHERE "tests"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
Traceback (most recent call last):
        1: from (irb):37
ActiveRecord::RecordNotFound (Couldn't find Test with 'id'=1)


#複数指定のうち1つが存在しない場合
irb(main):040:0> Test.find(8, 9, 1)
  Test Load (0.8ms)  SELECT "tests".* FROM "tests" WHERE "tests"."id" IN ($1, $2, $3)  [["id", 8], ["id", 9], ["id", 1]]
Traceback (most recent call last):
        1: from (irb):40
ActiveRecord::RecordNotFound (Couldn't find all Tests with 'id': (8, 9, 1) (found 2 results, but was looking for 3).)


カラムとデータを指定(find_by)

検索対象となるカラムとデータを指定して検索することもできます。(※データの1つがわかっている場合に使えます)

モデル名.find_by(カラム名:データ)
データ指定時の注意点
  • 大文字と小文字は区別されます。”1″と”1”は別ものです。
  • 該当がないとnilが返ります。
  • 結果はオブジェクトが返ります。

実例

#nameカラムがユーザー1のデータを検索
irb(main):063:0> Test.find_by(name:"ユーザー1")
  Test Load (0.9ms)  SELECT "tests".* FROM "tests" WHERE "tests"."name" = $1 LIMIT $2  [["name", "ユーザー1"], ["LIMIT", 1]]
=> #<Test id: 8, name: "ユーザー1", created_at: "2021-07-20 00:30:22.334075000 +0000", updated_at: "2021-07-20 00:30:22.334075000 +0000">


#データが存在しない場合
irb(main):064:0> Test.find_by(name:"ユーザー")
  Test Load (0.7ms)  SELECT "tests".* FROM "tests" WHERE "tests"."name" = $1 LIMIT $2  [["name", "ユーザー"], ["LIMIT", 1]]
=> nil


番号をアルファベットで指定 (first,,,fifth, last)

対象となるテーブルの中で何番目のデータが欲しいかを指定することもできます。指定は英語(序数)で行います。

※指定は1~5と、一番最後のみです(なぜか42 forty_two のみ指定できます。)

モデル名.英語表記の番号
利用可能な序数
  • first
  • second
  • third
  • forth
  • fifth
  • forty_two
  • last

実例

#first
irb(main):017:0> Test.first
  Test Load (0.5ms)  SELECT "tests".* FROM "tests" ORDER BY "tests"."id" ASC LIMIT $1  [["LIMIT", 1]]
=> #<Test id: 8, name: "ユーザー1", created_at: "2021-07-20 00:30:22.334075000 +0000", updated_at: "2021-07-20 00:30:22.334075000 +0000">


#thirtd
irb(main):018:0> Test.third
  Test Load (0.7ms)  SELECT "tests".* FROM "tests" ORDER BY "tests"."id" ASC LIMIT $1 OFFSET $2  [["LIMIT", 1], ["OFFSET", 2]]
=> #<Test id: 10, name: "ユーザー3", created_at: "2021-07-20 00:30:42.764326000 +0000", updated_at: "2021-07-20 00:30:42.764326000 +0000">


#last
irb(main):020:0> Test.last
  Test Load (0.5ms)  SELECT "tests".* FROM "tests" ORDER BY "tests"."id" DESC LIMIT $1  [["LIMIT", 1]]
=> #<Test id: 18, name: "ユーザー11", created_at: "2021-07-20 02:14:55.144603000 +0000", updated_at: "2021-07-20 02:14:55.144603000 +0000">


▼存在しない場合

  • 対象のデータが存在しない場合はnilが返ります。
  • メソッドが存在しない場合はエラーになります。(sixthやtenthなど)
#データが存在しない場合
irb(main):019:0> Test.forty_two
  Test Load (0.6ms)  SELECT "tests".* FROM "tests" ORDER BY "tests"."id" ASC LIMIT $1 OFFSET $2  [["LIMIT", 1], ["OFFSET", 41]]
=> nil


#メソッドがない場合
irb(main):021:0> Test.sixth
Traceback (most recent call last):
        1: from (irb):21
NoMethodError (undefined method `sixth' for #<Class:0x000055e8c803b018>)


条件で絞り込み(where)

最も実用的な検索方法は、whereを使って様々な条件の絞り込みを行うことです。

モデル名.where(条件)


条件の指定方法は複数あります。

  1. カラム名と値を指定 (カラム名: 値)
  2. 複数の条件を指定 (カラム名: [値1, 値2,,,])
  3. 以上、以下の指定 ("カラム名 > ?", 数値)("カラム名 <= ?", 数値)
  4. かつ(AND)の指定 where(条件).where(条件)
  5. かつ(AND)の指定 ("カラム名1=? and カラム名2=?", 値1, 値2)
  6. または(or)の指定 (条件).or(モデル名.where(条件))
  7. または(or)の指定 ("カラム名1=? or カラム名2=?", 値1, 値2)
  8. 否定 where.not(条件)
  9. nil以外 where.not(カラム名: nil)
  10. パターンを指定 ("カラム名 like?", "パターン")
  11. 否定パターンを指定 ("カラム名 not like?", "パターン")

whereメソッドの詳細については以下ページをご参考ください。

【Rails】whereメソッドの使い方まとめ。モデルを使って取得するテーブルの検索条件の絞り込みをする方法

実例

#idカラムの値が8, 9, 14のデータを検索
irb(main):046:0> Test.where(id:[8,9,14])
  Test Load (0.6ms)  SELECT "tests".* FROM "tests" WHERE "tests"."id" IN ($1, $2, $3) /* loading for inspect */ LIMIT $4  [["id", 8], ["id", 9], ["id", 14], ["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<Test id: 8, name: "ユーザー1", created_at: "2021-07-20 00:30:22.334075000 +0000", updated_at: "2021-07-20 00:30:22.334075000 +0000">, #<Test id: 9, name: "ユーザー2", created_at: "2021-07-20 00:30:31.939292000 +0000", updated_at: "2021-07-20 00:30:31.939292000 +0000">, #<Test id: 14, name: "ユーザー7", created_at: "2021-07-20 02:14:32.483212000 +0000", updated_at: "2021-07-20 02:14:32.483212000 +0000">]>


#カラムageが16以下を検索
irb(main):068:0> Student.where("age <= ? ", 16)
  Student Load (0.9ms)  SELECT "students".* FROM "students" WHERE (age <= 16 ) /* loading for inspect */ LIMIT $1  [["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<Student id: 3, name: "ケン", age: 16, gender: "男性", created_at: "2021-07-20 01:19:01.170922000 +0000", updated_at: "2021-07-20 01:19:01.170922000 +0000">]>

#whereをつなげて絞り込み(AND)
irb(main):080:0> Student.where(gender: "女性").where("age > ?", 16)
  Student Load (0.8ms)  SELECT "students".* FROM "students" WHERE "students"."gender" = $1 AND (age > 16) /* loading for inspect */ LIMIT $2  [["gender", 1], ["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<Student id: 2, name: "ジェシー", age: 17, gender: "女性", created_at: "2021-07-20 01:18:44.653383000 +0000", updated_at: "2021-07-20 01:18:44.653383000 +0000">, #<Student id: 4, name: "ジェニファー", age: 25, gender: "女性", created_at: "2021-07-20 01:19:15.589040000 +0000", updated_at: "2021-07-20 01:19:15.589040000 +0000">]>

#25歳以上か女性を検索
irb(main):095:0> Student.where("age >= ? or gender = ? ", 25, 1)
  Student Load (0.9ms)  SELECT "students".* FROM "students" WHERE (age >= 25 or gender = 1 ) /* loading for inspect */ LIMIT $1  [["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<Student id: 2, name: "ジェシー", age: 17, gender: "女性", created_at: "2021-07-20 01:18:44.653383000 +0000", updated_at: "2021-07-20 01:18:44.653383000 +0000">, #<Student id: 4, name: "ジェニファー", age: 25, gender: "女性", created_at: "2021-07-20 01:19:15.589040000 +0000", updated_at: "2021-07-20 01:19:15.589040000 +0000">, #<Student id: 5, name: "Danny", age: 32, gender: "男性", created_at: "2021-07-20 01:19:43.297445000 +0000", updated_at: "2021-07-20 01:19:43.297445000 +0000">]>


#nameカラムに「ー」を含む
irb(main):104:0> Student.where("name like?", "%ー%")
  Student Load (0.7ms)  SELECT "students".* FROM "students" WHERE (name like'%ー%') /* loading for inspect */ LIMIT $1  [["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<Student id: 1, name: "イチロー", age: 24, gender: "男性", created_at: "2021-07-20 01:18:23.633399000 +0000", updated_at: "2021-07-20 01:18:23.633399000 +0000">, #<Student id: 2, name: "ジェシー", age: 17, gender: "女性", created_at: "2021-07-20 01:18:44.653383000 +0000", updated_at: "2021-07-20 01:18:44.653383000 +0000">, #<Student id: 4, name: "ジェニファー", age: 25, gender: "女性", created_at: "2021-07-20 01:19:15.589040000 +0000", updated_at: "2021-07-20 01:19:15.589040000 +0000">]>


#nameカラムに「ー」を含まない
irb(main):111:0> Student.where("name not like?", "%ー%")
  Student Load (0.7ms)  SELECT "students".* FROM "students" WHERE (name not like'%ー%') /* loading for inspect */ LIMIT $1  [["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<Student id: 3, name: "ケン", age: 16, gender: "男性", created_at: "2021-07-20 01:19:01.170922000 +0000", updated_at: "2021-07-20 01:19:01.170922000 +0000">, #<Student id: 5, name: "Danny", age: 32, gender: "男性", created_at: "2021-07-20 01:19:43.297445000 +0000", updated_at: "2021-07-20 01:19:43.297445000 +0000">]>


テーブルに行を追加する(データの追加)

テーブルにデータ(行)を追加したい場合は次のコードを実行します。

モデル名.create(カラム名: 値)


データが複数ある場合は、カンマ「,」で区切ってカラム名: 値をつなげていきます。

モデル名.create(カラム名1: 値1, カラム名2: 値2, カラム名3: 値3, ,,,)

文字列はクオテーションで囲みます。(ダブルクオテーションでも大丈夫です)

自動割り振りのカラム

idや、created_at、updated_atなど、自動で数値が割り当てられるカラムは、指定しなくても問題ありません。

自分で指定することもできます。

実例

#テーブル一覧を表示
irb(main):001:0> ActiveRecord::Base.connection.tables
=> ["schema_migrations", "ar_internal_metadata", "clients", "active_admin_comments", "tests"]

#clientsテーブルのカラム一覧を表示
irb(main):003:0> Client.column_names
=> ["id", "pj_name", "client_name", "status", "order_date", "price", "memo", "created_at", "updated_at"]

irb(main):024:0> Client.create(pj_name:"最初のPJ", client_name:"クライアント1", status:0, order_date:"2021-1-1", price:4000)
  TRANSACTION (0.5ms)  BEGIN
  Client Create (4.1ms)  INSERT INTO "clients" ("pj_name", "client_name", "order_date", "price", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6) RETURNING "id"  [["pj_name", "最初のPJ"], ["client_name", "クライアント1"], ["order_date", "2021-01-01"], ["price", 4000], ["created_at", "2021-07-20 00:24:45.008452"], ["updated_at", "2021-07-20 00:24:45.008452"]]
  TRANSACTION (1.2ms)  COMMIT
=> #<Client id: 8, pj_name: "最初のPJ", client_name: "クライアント1", status: "契約前", order_date: "2021-01-01", price: 4000, memo: nil, created_at: "2021-07-20 00:24:45.008452000 +0000", updated_at: "2021-07-20 00:24:45.008452000 +0000">


一部のデータを変更する

一部のデータを変更するメソッドはバリデーションを実行するかや結果の返し方の違いで、いくつかのメソッドが用意されています。

メソッドバリデーション補足
updateバリデーションの実行結果をtrueかfalseで返す
update! バリデーションでエラーが発生した場合、例外を返す
update_attributesupdateのエイリアス
update_all×非推奨。すべての値を変更
update_attribute×非推奨

既に存在するデータを変更したい場合はupdateを使います。

モデル名.メソッド で絞り込んだ条件に対してupdateを実行します。(モデル名やモデル名.allを指定した場合は、すべての行のデータが同じ値になります)

対象.update(カラム名1:値1, カラム名2:値2, カラム名3:値3,,,)

実例

#updateの例
irb(main):088:0> Client.find(45).update(age:43)
  Client Load (0.7ms)  SELECT "clients".* FROM "clients" WHERE "clients"."id" = $1 LIMIT $2  [["id", 45], ["LIMIT", 1]]
=> true


#update_allの例
irb(main):091:0> Client.update_all(age:32)
  Client Update All (8.4ms)  UPDATE "clients" SET "age" = $1  [["age", "32"]]
=> 5
注意点

対象が複数ある場合は、すべて同じ状態になります。

例えば、モデルに対して直接updateを実行した場合や、allで抽出した結果に対して実施した場合です。

#Clientモデルに対してupdateを実施
irb(main):077:0> Client.update(name:"test1", age:60)
  Client Load (0.8ms)  SELECT "clients".* FROM "clients"
  TRANSACTION (0.5ms)  BEGIN
  Client Update (0.9ms)  UPDATE "clients" SET "updated_at" = $1, "age" = $2 WHERE "clients"."id" = $3  [["updated_at", "2021-07-24 06:07:32.129275"], ["age", "60"], ["id", 45]]
  TRANSACTION (8.8ms)  COMMIT
  TRANSACTION (0.4ms)  BEGIN
  Client Update (0.7ms)  UPDATE "clients" SET "updated_at" = $1, "name" = $2, "age" = $3 WHERE "clients"."id" = $4  [["updated_at", "2021-07-24 06:07:32.144103"], ["name", "test1"], ["age", "60"], ["id", 46]]
  TRANSACTION (4.5ms)  COMMIT
  TRANSACTION (0.4ms)  BEGIN
  Client Update (0.7ms)  UPDATE "clients" SET "updated_at" = $1, "name" = $2, "age" = $3 WHERE "clients"."id" = $4  [["updated_at", "2021-07-24 06:07:32.153690"], ["name", "test1"], ["age", "60"], ["id", 47]]
  TRANSACTION (7.4ms)  COMMIT
  TRANSACTION (0.3ms)  BEGIN
  Client Update (0.6ms)  UPDATE "clients" SET "updated_at" = $1, "name" = $2, "age" = $3 WHERE "clients"."id" = $4  [["updated_at", "2021-07-24 06:07:32.166784"], ["name", "test1"], ["age", "60"], ["id", 48]]
  TRANSACTION (3.9ms)  COMMIT
  TRANSACTION (0.3ms)  BEGIN
  Client Update (0.5ms)  UPDATE "clients" SET "updated_at" = $1, "name" = $2, "age" = $3 WHERE "clients"."id" = $4  [["updated_at", "2021-07-24 06:07:32.174441"], ["name", "test1"], ["age", "60"], ["id", 49]]
  TRANSACTION (6.0ms)  COMMIT
=> [#<Client id: 45, created_at: "2021-07-24 06:06:32.776847000 +0000", updated_at: "2021-07-24 06:07:32.129275000 +0000", name: "test1", age: "60">, #<Client id: 46, created_at: "2021-07-24 06:06:36.718371000 +0000", updated_at: "2021-07-24 06:07:32.144103000 +0000", name: "test1", age: "60">, #<Client id: 47, created_at: "2021-07-24 06:06:39.738684000 +0000", updated_at: "2021-07-24 06:07:32.153690000 +0000", name: "test1", age: "60">, #<Client id: 48, created_at: "2021-07-24 06:06:43.535459000 +0000", updated_at: "2021-07-24 06:07:32.166784000 +0000", name: "test1", age: "60">, #<Client id: 49, created_at: "2021-07-24 06:06:47.729251000 +0000", updated_at: "2021-07-24 06:07:32.174441000 +0000", name: "test1", age: "60">]


データを削除する方法

不要な行を削除する方法は2つあります。

  1. destroy: 渡された1つのデータのみを削除(1つ以上の場合はエラーになる)
  2. destroy_all : 渡されたデータをすべて削除
注意点

destroyとdestroy_allの違いは、正確には、使える対象が異なります。

destroyメソッドが使える対象はオブジェクトです。allやwhereメソッドの結果はActiveRecord::Relationなのでdestroyメソッドは使えません。(whereメソッドの検索結果が1つのみです削除できません)

ActiveRecord::Relationのデータを削除したい場合は、destroy_allを使います。

逆に、オブジェクトにdestroy_allは使えません。

destroy: 渡された1つのデータのみを削除

destroyメソッドを使うと、渡された1つのデータのみを削除することができます。

対象はオブジェクトのみです。ActiveRecord::Relationに対しては使えません(エラーになります)。

モデル名.対象を抽出するメソッド.destroy

実例

#3番目の行を削除
irb(main):032:0> Client.third.destroy
  Client Load (0.6ms)  SELECT "clients".* FROM "clients" ORDER BY "clients"."id" ASC LIMIT $1 OFFSET $2  [["LIMIT", 1], ["OFFSET", 2]]
  TRANSACTION (0.5ms)  BEGIN
  Client Destroy (0.5ms)  DELETE FROM "clients" WHERE "clients"."id" = $1  [["id", 41]]
  TRANSACTION (4.9ms)  COMMIT
=> #<Client id: 41, created_at: "2021-07-24 04:21:15.273201000 +0000", updated_at: "2021-07-24 04:21:15.273201000 +0000", name: "test3", age: "22">


#age=20となる行を削除

▼エラー例

#複数の行を削除しようとするとエラーになる
irb(main):016:0> Client.all.destroy
Traceback (most recent call last):
ArgumentError (wrong number of arguments (given 0, expected 1))


#whereメソッドの結果に使うとエラーになる
irb(main):050:0> Client.where(name:"test").destroy
Traceback (most recent call last):
        1: from (irb):50
ArgumentError (wrong number of arguments (given 0, expected 1))



destroy_all : 渡されたデータをすべて削除

destroy_allメソッドを使うと、渡されたすべてのデータを削除することができます。

対象はActiveRecord::Relationのみです。オブジェクトに対しては使えません(エラーになります)。

モデル名.対象を抽出するメソッド.destroy_all

実例

#すべてのデータを削除
irb(main):069:0> Client.all.destroy_all
  Client Load (0.9ms)  SELECT "clients".* FROM "clients"
  TRANSACTION (0.3ms)  BEGIN
  Client Destroy (0.7ms)  DELETE FROM "clients" WHERE "clients"."id" = $1  [["id", 42]]
  TRANSACTION (6.0ms)  COMMIT
  TRANSACTION (0.4ms)  BEGIN
  Client Destroy (0.6ms)  DELETE FROM "clients" WHERE "clients"."id" = $1  [["id", 44]]
  TRANSACTION (4.2ms)  COMMIT
=> [#<Client id: 42, created_at: "2021-07-24 04:21:19.354113000 +0000", updated_at: "2021-07-24 04:21:19.354113000 +0000", name: "test4", age: "24">, #<Client id: 44, created_at: "2021-07-24 06:02:42.058460000 +0000", updated_at: "2021-07-24 06:02:42.058460000 +0000", name: "test", age: "30">]


#whereメソッドの結果を削除
irb(main):068:0> Client.where("name = ?", "test5").destroy_all
  Client Load (0.9ms)  SELECT "clients".* FROM "clients" WHERE (name = 'test5')
  TRANSACTION (0.4ms)  BEGIN
  Client Destroy (0.6ms)  DELETE FROM "clients" WHERE "clients"."id" = $1  [["id", 43]]
  TRANSACTION (6.4ms)  COMMIT
=> [#<Client id: 43, created_at: "2021-07-24 04:21:24.925456000 +0000", updated_at: "2021-07-24 04:21:24.925456000 +0000", name: "test5", age: "26">]

▼エラー例

#オブジェクトに対しては使えない(find_byメソッド)
irb(main):065:0> Client.find_by(name:"test").destroy_all
  Client Load (0.7ms)  SELECT "clients".* FROM "clients" WHERE "clients"."name" = $1 LIMIT $2  [["name", "test"], ["LIMIT", 1]]
Traceback (most recent call last):
        1: from (irb):65
NoMethodError (undefined method `destroy_all' for #<Client:0x000056459ba04c18>)
Did you mean?  destroy


#オブジェクトに対しては使えない(findメソッド)
irb(main):066:0> Client.find(42).destroy_all
  Client Load (0.5ms)  SELECT "clients".* FROM "clients" WHERE "clients"."id" = $1 LIMIT $2  [["id", 42], ["LIMIT", 1]]
Traceback (most recent call last):
        2: from (irb):65
        1: from (irb):66:in `rescue in irb_binding'
NoMethodError (undefined method `destroy_all' for #<Client:0x000056459b1e49e8>)
Did you mean?  destroy


テーブルのカラムを追加・名前変更・削除・データ型を変更する方法

モデル経由でテーブルを操作できるのは、テーブルや中身の表示、一部のデータの追加・変更・削除です。

テーブルのカラムの追加・名前変更・削除・データ型を変更といったスキーマ自体の変更はマイグレーションファイル経由で行う必要があります。

テーブルのカラムを追加・名前変更・削除・データ型を変更する方法については下記をご参考ください。

【Rails】テーブルやカラムの追加・名前の変更・削除・データ型を変更する方法を実例で解説


テーブルを削除する方法

テーブルの削除も、テーブルのカラム自体の変更と同じく、スキーマの変更となるのでモデル経由で行うことはできません。マイグレーションファイル経由で行う必要があります。

テーブルの削除方法と注意点については下記をご参考ください。

【Rails】テーブル削除(drop_table)の注意点! エラー対処法:ActiveRecord::IrreversibleMigration

タイトルとURLをコピーしました