知っていたら実務で最強!Railsコンソールの使い方を実務ベースで解説
Railsコンソールとはそもそも何か
Railsで提供されている対話型のコマンドラインツールです。
アプリ内のモデルやコントローラのメソッドを呼び出すことができ、
データベースのレコードを作成、更新、削除ができます。
以下のコマンドで立ち上げることができます。
# rails
# rails console
実行環境の確認
開発において環境は3種類あります。
1.開発環境 (development)
: 開発者がアプリケーションを開発するための環境。
2.テスト環境 (test)
: RSpecなどで使われユニットテストや統合テストがこの環境で実行。
3.本番環境 (production)
:アプリケーションを実際に運用される環境でユーザーはここを使用。
⚫︎補足
staging環境は今回はなし!
まず自分が今どの環境にいるのか確認します。コンソールで入った後にRails.env
を実行します。
irb(main):001> Rails.env
=> "development"
今開発環境にいることがわかります。envはenviromentのenv
です。
コンソールのコマンドによって環境を変えることができます。
# rails c #開発環境の入り方
Loading development environment (Rails 7.0.8)
irb(main):001> Rails.env
=> "development"
# rails c -e test #テスト環境の入り方
Loading test environment (Rails 7.0.8)
irb(main):001> Rails.env
=> "test"
# rails c -e production #本番環境入り方
Rails6以降だと他にも以下のやり方でも起動できるみたいです。
RAILS_ENV=[環境] rails c
rails c --environment [環境]
実際に動かしてみましょうか。
1.開発環境
# RAILS_ENV= rails c
Loading development environment (Rails 7.0.8)
irb(main):001> Rails.env
=> "development"
2.テスト環境
# rails c --environment test
Loading test environment (Rails 7.0.8)
irb(main):001> Rails.env
=> "test"
⚫︎補足
RAILS_ENV=[環境] rails cのテストはどうやら廃止になったみたいですね。
実際にコンソールを動かしてみる
実際に実務でやった手順を解説します。
ユーザーのデータが全く入っていなかったのでデータを入れるために実行しました。
irb(main):001> User.new
=>
=>
#<User:〇〇
id: nil,
member_id: nil,
member_name: nil,
deleted_at: nil,
created_at: nil,
updated_at: nil>
User.new
ですが、Userモデルの新しいインスタンスを生成
しています。
そのままcreate
をします。createしたらsaveは不要です。
理由はクラスメソッドだからです。
irb(main):002> User.create(member_id:"123",member_name:"Mike")
TRANSACTION (0.8ms) BEGIN
User Create (7.8ms) INSERT INTO "users" ("member_id", "member_name", "deleted_at", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [["slack_id", "123"], ["slack_name", "go"],["deleted_at", nil], ["created_at", "2023-11-20 10:18:51.303718"], ["updated_at", "2023-11-20 10:18:51.303718"]]
TRANSACTION (2.7ms) COMMIT
=>
#<User:〇〇
id: 1,
member_id: "123",
member_name: "Mike",
deleted_at: nil,
created_at: Mon, 20 Nov 2023 10:18:51.303718000 UTC +00:00,
updated_at: Mon, 20 Nov 2023 10:18:51.303718000 UTC +00:00>
⚫︎補足❗️
newするだけならsaveは必要
です。
user = User.new
user.save
データは1つしかないですが、User.allで取得してみます。
irb(main):004> User.all
User Load (0.7ms) SELECT "users".* FROM "users"
=>
[#<User:〇〇
id: 1,
member_id: "123",
member_name: "Mike",
deleted_at: nil,
created_at: Mon, 20 Nov 2023 10:18:51.303718000 UTC +00:00,
updated_at: Mon, 20 Nov 2023 10:18:51.303718000 UTC +00:00>]
userと投稿を紐付け
データが取れているのを確認したらexitしてuserと投稿を紐付けします。
# rails c
Loading development environment (Rails 7.0.8)
irb(main):001> Post.new
=>
#<Post:〇〇
id: nil,
user_id: nil,
timestamps: nil,
deleted_at: nil,
created_at: nil,
updated_at: nil>
Userの情報を確認します。
irb(main):002> User.last
User Load (0.7ms) SELECT "users".* FROM "users" ORDER BY "users"."id" DESC LIMIT $1 [["LIMIT", 1]]
=>
#<User:〇〇
id: 1,
member_id: "123",
member_name: "Mike",
deleted_at: nil,
created_at: Mon, 20 Nov 2023 10:18:51.303718000 UTC +00:00,
updated_at: Mon, 20 Nov 2023 10:18:51.303718000 UTC +00:00>
irb(main):003> User.last.id
User Load (0.9ms) SELECT "users".* FROM "users" ORDER BY "users"."id" DESC LIMIT $1 [["LIMIT", 1]]
=> 1
またこの後もcreateします。
irb(main):004> Post.create(user_id:1)
TRANSACTION (0.4ms) BEGIN
User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
Post Create (4.8ms) INSERT INTO "posts" ("user_id", "timestamps", "deleted_at", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [["user_id", 1], ["timestamps", nil], ["deleted_at", nil], ["created_at", "2023-11-20 10:33:51.550814"], ["updated_at", "2023-11-20 10:33:51.550814"]]
TRANSACTION (1.1ms) COMMIT
=>
#<Post:〇〇
id: 1,
user_id: 1,
timestamps: nil,
deleted_at: nil,
created_at: Mon, 20 Nov 2023 10:33:51.550814000 UTC +00:00,
updated_at: Mon, 20 Nov 2023 10:33:51.550814000 UTC +00:00>
日報の情報を確認してみます。
irb(main):005> Post.last
Post Load (0.5ms) SELECT "posts".* FROM "posts" ORDER BY "posts"."id" DESC LIMIT $1 [["LIMIT", 1]]
=>
#<Post:0x00007f5155427518
id: 1,
user_id: 1,
timestamps: nil,
deleted_at: nil,
created_at: Mon, 20 Nov 2023 10:33:51.550814000 UTC +00:00,
updated_at: Mon, 20 Nov 2023 10:33:51.550814000 UTC +00:00>
ユーザーの情報も確認してみます。
irb(main):006> User.last
User Load (0.7ms) SELECT "users".* FROM "users" ORDER BY "users"."id" DESC LIMIT $1 [["LIMIT", 1]]
=>
#<User:〇〇
id: 1,
member_id: "123",
member_name: "Mike",
deleted_at: nil,
created_at: Mon, 20 Nov 2023 10:18:51.303718000 UTC +00:00,
updated_at: Mon, 20 Nov 2023 10:18:51.303718000 UTC +00:00>
取得した最後のユーザーに対して、postsメソッドを呼び出しています。
irb(main):007> User.last.posts
User Load (0.6ms) SELECT "users".* FROM "users" ORDER BY "users"."id" DESC LIMIT $1 [["LIMIT", 1]]
Post Load (0.7ms) SELECT "posts".* FROM "posts" WHERE "posts"."user_id" = $1 [["user_id", 1]]
=>
[#<Post:〇〇
id: 1,
user_id: 1,
timestamps: nil,
deleted_at: nil,
created_at: Mon, 20 Nov 2023 10:33:51.550814000 UTC +00:00,
updated_at: Mon, 20 Nov 2023 10:33:51.550814000 UTC +00:00>]
createでまたPostのデータを作ろうと思います。
irb(main):009> Post.create(user_id:1)
#中略
irb(main):010> Post.create(user_id:1)
#中略
user_idが1のデータをcountを使って確認します。
irb(main):011> User.last.posts.count
User Load (1.0ms) SELECT "users".* FROM "users" ORDER BY "users"."id" DESC LIMIT $1 [["LIMIT", 1]]
Post Count (0.8ms) SELECT COUNT(*) FROM "posts" WHERE "posts"."user_id" = $1 [["user_id", 1]]
=> 3
これで3つデータができたことがわかります。
最後確認してみましょう。
irb(main):012> User.last.posts
User Load (0.6ms) SELECT "users".* FROM "users" ORDER BY "users"."id" DESC LIMIT $1 [["LIMIT", 1]]
Post Load (0.4ms) SELECT "posts".* FROM "posts" WHERE "posts"."user_id" = $1 [["user_id", 1]]
=>
[#<Post:〇〇
id: 1,
user_id: 1,
timestamps: nil,
deleted_at: nil,
created_at: Mon, 20 Nov 2023 10:33:51.550814000 UTC +00:00,
updated_at: Mon, 20 Nov 2023 10:33:51.550814000 UTC +00:00>,
#<Post:〇〇
id: 2,
user_id: 1,
timestamps: nil,
deleted_at: nil,
created_at: Mon, 20 Nov 2023 10:36:15.774006000 UTC +00:00,
updated_at: Mon, 20 Nov 2023 10:36:15.774006000 UTC +00:00>,
#<Post:〇〇
id: 3,
user_id: 1,
timestamps: nil,
deleted_at: nil,
created_at: Mon, 20 Nov 2023 10:36:20.317372000 UTC +00:00,
updated_at: Mon, 20 Nov 2023 10:36:20.317372000 UTC +00:00>]
user_idのデータが3つ取れました。
削除の方法
投稿のデータを全部削除するやり方は以下の通りです。
irb(main):001> Post.all
#中略
irb(main):002> Post.destroy_all
特定のデータでuser_idが1のデータを削除する場合は以下のやり方をします。
irb(main):001> Post.where(user_id: 1).destroy_all
deleted_at カラムが nil でないものを削除する場合は
irb(main):001> Post.where.not(deleted_at: nil).destroy_all
です。
Post.allで全部削除する方法は
# Post.all で取得した全ての投稿を削除
Post.destroy_all
# Post.all で取得した全ての投稿を直接データベースから削除
Post.delete_all
です。
基本的な使い方
基本的なデータベース操作例も見ていきます。
- Userモデルの新しいユーザーを作成して保存
user = User.new(name: "Messi", email: "messi@example.com")
user.save
- 最初のユーザーを取得
user = User.first
- 条件に合致するユーザーを取得
users = User.where(age: 35)
- ユーザーの名前を更新
user = User.first
user.update(name: "Ronald")
- 最初のユーザーを削除
user = User.first
user.destroy
5番目以降のデータはどうやって取得するのか
上記のようにUserの最初や2番目のデータはfirstやsecond
で取得できます。
1番目から5番目のデータは以下のように取得できます。
user = User.first
user = User.second
user = User.third
user = User.fourth
user = User.fifth
6番目以降のデータで
[1] pry(main)> User.sixth
NoMethodError: undefined method `sixth' for #中略
になってしまいます。6番目以降は以下のやり方で取得できました。
User.offset(5).limit(1).first #6番目
User.offset(6).limit(1).first #7番目
User.offset(7).limit(1).first #8番目
例えば、offset 6(7番目のレコード)を指定
して、1つのレコードのみを取得することで、7番目のレコードを取得します。
モデルの7番目のレコードを取得するためには、offset を使用してフィルタリングを行う必要があります。offset
は指定した数だけ結果をスキップします。
offset には1から始まるインデックスを使うのではなく、0から始まるインデックスを使うことに注意してください。
用語の解説
補足で用語の解説をしていきます。ChatGPTを参考にしました。
-
インスタンス
あるものの具体的な実体や例のことです。例えば、車の型(設計図)があるとします。
その型に基づいて実際に作られた車が、その型の「インスタンス」 です。
車の型ができたとするとその型が「ベンツ」だとすると、それに基づいて作られた実際のベンツが「ベンツのインスタンス」です。
プログラミングの世界でも例えてみます。例えば、あるプログラムで作成された「データの型」があるとします。その型に基づいて作成された実際のデータが、その型の「インスタンス」です。プログラムの中で、「User(ユーザー)」という型があった場合、それに基づいて作られた1人のユーザーが「Userのインスタンス」です。
つまり 「インスタンス」とは、抽象的な概念や設計図に基づいて実際に作られた具体的なもののことです。
-
クラスメソッド
クラスメソッドは、あるクラス(例えば、Userというクラス)全体に関連する動作や処理を行うための特別なメソッドです。これは、クラス自体に対して呼び出され、クラスに関する操作を実行します。小学生にわかりやすく説明すると、以下のようになります。
クラスは、抽象的な概念や設計図です。例えば、Animalというクラスがあるとします。
このクラスには 「動物」の習性や特徴(メソッド)が定義 されています。例えば、「夜行性」や「肉食」といったメソッドがあります。
ここで、「動物」を一瞬で作りたいとなった時に実現するのがクラスメソッドです。
クラスメソッドは、クラス全体に対して影響を与えることができる特別なメソッドです。
例えば、「動物を作る」というクラスメソッドを呼び出すことで、
新しい動物が一斉に作られるイメージです。
実際のプログラムで言うと、以下のようになります。例えば、Animalクラスがあって、そのクラスに「みんなの動物を作る」クラスメソッドがあるとします。
class Animal
def self.create_animal
puts "動物ができた!"
end
end
# クラスメソッドを呼び出す
Animal.create_animal
このプログラムを実行すると、「動物ができた!」と表示されます。クラスメソッドはselfキーワードを使って定義され、そのクラス自体に対して呼び出されることが特徴です。
-
インスタンス変数
あとnewとsaveはインスタンス変数ですか。インスタンス変数を小学生にもわかるように書いてください。
インスタンス変数は、オブジェクト(もの)に関連する情報を保存するための特別な入れ物のようなものです。
例えば、ある動物のオブジェクトがあったときに、その動物が「名前」や「色」などの情報を持つ場合、それらの情報をデータとして入れておくことができます。このデータがインスタンス変数です。
インスタンス変数に入れておくことができます。
コンソールでnewとsaveで、動物の例で考えてみましょう。
new(新しく作る):
newは、新しい動物を作るための工程です。例えば、newを使って「サル」を作ると、
サルは新しくできたところで、まだ具体的な名前や色が決まっていません。
これをプログラムで表現すると、次のようになります:
monkey = Monkey.new
ここでmonkeyはサルのインスタンスを表しています。このとき、Monkeyクラスの中には
「種類」や「生息地」などが入れられる特別なポケット(インスタンス変数)がありますが、まだ具体的な情報は入っていません。
save(保存する)
saveは、サルに具体的な情報を入れて、それを保存する工程です。
例えば、サルに名前が「ウッキー」、色が「茶色」だと決まったら、それをsaveして保存します。
これをプログラムで表現すると
monkey.name = "ウッキー"
monkey.color = "茶色"
monkey.save
ここで、nameやcolorはサルが持っている特別なポケット(インスタンス変数)に情報を入れることを示しています。そして、saveはその情報を保存して、サルに具体的な名前や色が入った状態で完成させます。
簡単に言えば、newは新しいものを作り、saveはそれに具体的な情報を入れて保存します。
このとき、具体的な情報はインスタンス変数に入れられていると考えることができます。
参考資料
Discussion