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
  1. self.upメソッド --- members という新しいテーブルを作成します。
    • email: 最大255文字の文字列。必須項目(null: false)。
    • name: 最大64文字の文字列。必須項目。
    • status: 整数型。デフォルト値は1。
    • admin: 真偽値(boolean)。デフォルト値はfalse。
    • timestamps: レコードの作成日時と更新日時を記録する2つのカラム(created_atとupdated_at)。
    • また、email列に一意性を持たせるインデックス(unique: true)を追加しています。
  2. 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です。

今回はこの辺で...

コメント

このブログの人気の投稿

docker-compose up で proxyconnect tcp: dial tcp: lookup proxy.example.com: no such host

【Android】Fragmentを使う② - ActivityとFragmentの相互呼び出し -

【Java】ObjectMapperでJSONデータを変数に取り込む