WSL2(Ubuntu)のDocker+Ruby on Railsでデータベース運用
前回の記事 でローカルのWSL上にRuby on Railsの開発環境を構築しました。今回はRailsアプリケーションからデータベースの操作(DDL/DML)を行う方法をまとめていきます。
事前準備
バージョン情報
Ruby | ruby 3.2.3 (2024-01-18 revision 52bb2ac0a6) [x86_64-linux-gnu] |
---|---|
Rails | Rails 8.0.2 |
ライブラリセットアップ
Ruby
RubyGemsというRubyのパッケージ管理システムを利用するため、以下コマンドでrubyをセットアップします。
sudo apt install ruby-full
ruby --version
Rails
gemコマンドが使用できるようになるので、gemコマンドでrailsをセットアップします。
sudo gem install rails
rails --version
権限変更
Railsアプリケーションが暗号化された資格情報や環境変数を復号するための秘密鍵として使用するためマスターキーや、ログディレクトリへのアクセスを可能にするために以下コマンドで権限を変更します。
マスターキー
sudo chown $(whoami) config/master.key
ログディレクトリ権限変更
sudo chown $(whoami) log
sudo chmod 766 log
DBディレクトリ権限変更
sudo chown $(whoami) db
sudo chmod 766 db
確認
この状態でいったんrails dbコマンドが問題なく使えるか確認します。
rails db:migrate:status
以下のように出力されればOKです。
database: myapp_development Status Migration ID Migration Name --------------------------------------------------
DBマイグレーション
DBマイグレーションとは、データベースの構造を変更する作業のことです。例えば、新しいテーブルを追加したり、既存のテーブルに新しいカラムを追加したりすることが含まれます。
Railsなどのフレームワークでは、マイグレーションファイルという専用のファイルを作成して、その中に変更内容を記述します。これを使うと、変更を簡単に管理できてデータベースの運用に非常に便利です。
マイグレーションファイル作成
基本構文
rails g migration {マイグレーションファイル名}
マイグレーションファイル名は自由に決めることができますが、「テーブルに対する操作+テーブル名」で付けるのが一般的です。
新規テーブル作成
マイグレーションファイル作成コマンド
rails g migration create_members
マイグレーションファイルの作成に成功すると以下のように出力され、db/migrate/配下にファイルが生成されます。
invoke active_record create db/migrate/20250510020738_create_members.rb
create_members.rb
生成されたdb/migrate/xxxxxxxxxx_create_members.rbを開き、内容を以下のようにします。
class CreateMembers < ActiveRecord::Migration[8.0]
def self.up
create_table :members do |t|
t.column :email, :string, :null => false, limit: 255
t.column :name, :string, :null => false, limit: 64
t.column :status, :integer, :null => false, default: 1
t.column :admin, :boolean, :null => false, default: false
t.timestamps
end
add_index :members, :email, unique: true
end
def self.down
remove_index :members, :email
drop_table :members
end
end
- self.upメソッド --- members という新しいテーブルを作成します。
- email: 最大255文字の文字列。必須項目(null: false)。
- name: 最大64文字の文字列。必須項目。
- status: 整数型。デフォルト値は1。
- admin: 真偽値(boolean)。デフォルト値はfalse。
- timestamps: レコードの作成日時と更新日時を記録する2つのカラム(created_atとupdated_at)。
- また、email列に一意性を持たせるインデックス(unique: true)を追加しています。
- self.upメソッド --- self.up メソッドで行った操作を取り消す処理を定義しています。
- emailのインデックスを削除します。
- membersテーブルそのものを削除します。
ステータス確認
マイグレーションファイルを用意したら先ほどと同じステータスコマンドで現在の状態を確認します。
rails db:migrate:status
今度は以下のように出力されます。
database: myapp_development Status Migration ID Migration Name -------------------------------------------------- down 20250510020738 Create members
この状態では、Create members マイグレーションはまだ適用されていないということを示しています。マイグレーションのステータスが "down" なので、テーブルやカラムの作成など、マイグレーションの内容がデータベースに反映されていない状態です。
マイグレーション実行
:statusをとって実行すれば、Create members マイグレーションを実行することができます。
rails db:migrate
== 20250510020738 CreateMembers: migrating ==================================== -- create_table(:members) -> 0.1967s -- add_index(:members, :email, {:unique=>true}) -> 0.1346s == 20250510020738 CreateMembers: migrated (0.3316s) ===========================
再度ステータスを確認するとStatusが"up"に変わり、マイグレーションファイルが実行されたことが確認できます。
rails db:migrate:status
database: myapp_development Status Migration ID Migration Name -------------------------------------------------- down 20250510020738 Create members
ロールバック
rollbackコマンドで直前のマイグレーションをロールバックすることができます。この時、マイグレーションファイルに用意したself.downメソッドが実行されます。
rails db:rollback
== 20250510020738 CreateMembers: reverting ==================================== -- remove_index(:members, :email) -> 0.0456s -- drop_table(:members) -> 0.0378s == 20250510020738 CreateMembers: reverted (0.0838s) ===========================
再度ステータスを確認するとStatusが"down"に変わり、マイグレーションファイルが実行前の状態となったことが分かります。
rails db:migrate:status
database: myapp_development Status Migration ID Migration Name -------------------------------------------------- down 20250510020738 Create members
初期化
resetコマンドでマイグレーションを初期化することができます。
rails db:reset
結果を確認すると、self.downメソッドが呼ばれた後、再度self.upメソッドが呼ばれていることが分かります。
Dropped database 'myapp_development' Dropped database 'myapp_test' Created database 'myapp_development' Created database 'myapp_test' == 20250510020738 CreateMembers: migrating ==================================== -- create_table(:members) -> 0.0510s -- add_index(:members, :email, {:unique=>true}) -> 0.0469s == 20250510020738 CreateMembers: migrated (0.0983s) ===========================
DBシード
RailsのDBシード(db:seed)は、データベースに初期データを簡単に投入するための仕組みです。
Memberモデル作成
モデルを使ってシードデータの投入を行うので、まず以下コマンドでモデルを作成します。このコマンドはマイグレーションファイルも作ろうとするのでconflictエラーが発生しますが、無視でよいのでSkipオプションを付けています。
sudo rails generate model member --skip
環境ごとにシードデータを投入する設定
シードデータはdb/seeds.rbに設定しますが、環境ごとに投入するデータを分けたい場合以下のようにします。
db/seeds.rb
db/seeds.rbに以下コードを追記します。
environment_seeds = File.join(Rails.root, 'db', 'seeds', "#{Rails.env}.rb")
if File.exist?(environment_seeds)
puts "Loading seeds for #{Rails.env} environment..."
require(environment_seeds)
else
puts "No seeds file found for #{Rails.env} environment."
end
DBシードファイル作成
ディレクトリ&ファイル作成
以下手順でDev用のシードデータを作成します。
mkdir db/seeds
touch db/seeds/development.rb
development.rb
# db/seeds/development.rb
## members
Member.destroy_all
Member.create([
{
email: "dev_member1@example.com",
name: "Dev Member 1",
},
{
email: "dev_member2@example.com",
name: "Dev Member 2",
}
])
DBシードデータ投入
db:seed実行
rails db:seed
Loading seeds for development environment...
確認
rails cコマンドで対話モードでデータ確認ができます。(※rails cについては別で記事にしたいと思います。)
rails c
Member.all()
Loading development environment (Rails 8.0.2) myapp(dev)> Member.all() Member Load (75.9ms) SELECT `members`.* FROM `members` /* loading for pp */ LIMIT 11 /*application='Myapp'*/ => [#<Member:0x00007fec4475a278 id: 1, email: "[FILTERED]", name: "Dev Member 1", status: 1, admin: false, created_at: "2025-05-10 15:41:41.084919000 +0000", updated_at: "2025-05-10 15:41:41.084919000 +0000">, #<Member:0x00007fec43fa6040 id: 2, email: "[FILTERED]", name: "Dev Member 2", status: 1, admin: false, created_at: "2025-05-10 15:41:41.109504000 +0000", updated_at: "2025-05-10 15:41:41.109504000 +0000">]
emailの値が[FILTERED]となっているのは、セキュリティの観点から、特定の情報が意図せずログに出力されるのを防ぐ仕組みがよるものです。この場合、[FILTERED] と表示されているのは、config.filter_parameters による設定が原因です。
もちろんほかのDBクライアントツール等を使用してDB接続してOKです。
今回はこの辺で...
コメント
コメントを投稿