こんにちは。ryohei515です。
実務で ActiveRecord の動作を確認したいときは、開発環境内の Rails Console で動かしてみるのですが、プライベートで確認したい時用に環境を作っておきたいと思い、備忘録的に残しておきます。
過去の記事で、サンプルデータを使って DB を触れる環境を作ってみたので、今回はそれを Rails から触れるようにしようと思います。
1. データ準備
以下のサンプルデータを使用します。データがほどよくあるので便利です。
PostgreSQL Sample Database
ダウンロードしたファイルは unzip
コマンドで解凍しておきます。
unzip ./dvdrental.zip
2. Docker関連のファイルを作成
Docker の公式サイトを参考に、Rails の環境を構築してみます。
クィックスタート: Compose と Rails — Docker-docs-ja 19.03 ドキュメント
ただ、掲載の Rails, Ruby のバージョンが少し古いので、こちらを参考に、Rails は 6.1.6、Ruby は 2.7.6 を利用するようにします。
適当にディレクトリを作成して、以下の4ファイルを配置します。
docker-compose.yml
version: '3.8' services: db: image: postgres:14.2-alpine ports: - "5432:5432" volumes: - db-data:/var/lib/postgresql/data environment: POSTGRES_USER: postgres POSTGRES_PASSWORD: password web: build: . command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'" volumes: - .:/myapp ports: - "3000:3000" depends_on: - db volumes: db-data:
Dockerfile
FROM ruby:2.7.6 RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \ echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs yarn RUN mkdir /myapp WORKDIR /myapp ADD Gemfile /myapp/Gemfile ADD Gemfile.lock /myapp/Gemfile.lock RUN bundle install ADD . /myapp
Gemfile
source 'https://rubygems.org' gem 'rails', '~> 6.1.6'
Gemfile.lock
(空ファイルで作成しておく。)
3. Rails プロジェクトを作成
以下のコマンドを実行して、ディレクトリを作ります。
docker-compose run --rm web rails new . --force --database=postgresql
4. データを DB に反映させる
3 の手順により、DB のコンテナが立ち上がったままとなっているので、起動させたコンテナのIDを特定し、ファイルをコピーします
docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ce4299b2c1c6 postgres:14.2-alpine "docker-entrypoint.s…" About an hour ago Up About an hour 0.0.0.0:5432->5432/tcp rails-docker-trial_db_1 docker cp /tmp/dvdrental.tar ce4299b2c1c6:/
起動中の DB コンテナに入り、コピーしたファイルをDBに復元させます。
dc exec db bash bash-5.1# psql -h localhost -U postgres -c "CREATE DATABASE dvdrental;" bash-5.1# pg_restore -h localhost -U postgres -d dvdrental ./dvdrental.tar
これでサンプルデータが DB に反映された状態になりました。
ただこのサンプルデータには、 独自に追加された型定義があるため、このままだと Rails 側でスキーマ情報を反映させた時エラーとなります。
そのため、その独自の型定義を使用している、film
テーブルの rating
を String に置き換えます。
(View でも利用されており、View を削除しないと型定義が変更できないため、先に削除します)
psql -h localhost -U postgres -d dvdrental psql (14.2) Type "help" for help. dvdrental=# DROP VIEW film_list; DROP VIEW dvdrental=# DROP VIEW nicer_but_slower_film_list; DROP VIEW dvdrental=# ALTER TABLE film ALTER COLUMN rating TYPE varchar(255); ALTER TABLE dvdrental=# ALTER TABLE film ALTER COLUMN rating SET DEFAULT 'G'; ALTER TABLE
5. Rails から DB にアクセスできるようにする。
config/database.yml
は以下のように記載しておきます。
default: &default adapter: postgresql encoding: unicode host: db username: postgres password: password pool: 5 development: <<: *default database: dvdrental test: <<: *default database: dvdrental_test
その後、web
コンテナに入り DB の定義から db/schema.rb
を作成します。
docker-compose run --rm web bash root@90f53214db3a:/myapp# bin/rails db:create root@90f53214db3a:/myapp# bin/rails db:schema:dump
あとは存在するテーブルの model を作成し
bin/rails g model film --migration=false
(Rails の命名規則に従ったテーブル名ではないため)作成した model にテーブル名を指定してあげれば、Rails Console から扱えるようになります。
class Film < ApplicationRecord self.table_name = 'film' end
bin/rails console Running via Spring preloader in process 90 Loading development environment (Rails 6.1.6) irb(main):001:0> Film.first Film Load (1.8ms) SELECT "film".* FROM "film" ORDER BY "film"."film_id" ASC LIMIT $1 [["LIMIT", 1]] => #<Film film_id: 1, title: "Academy Dinosaur", description: "A Epic Drama of a Feminist And a Mad Scientist who...", release_year: 2006, language_id: 1, rental_duration: 6, rental_rate: 0.99e0, length: 86, replacement_cost: 0.2099e2, rating: "PG", last_update: "2013-05-26 14:50:58.951000000 +0000", special_features: ["Deleted Scenes", "Behind the Scenes"], fulltext: "'academi':1 'battl':15 'canadian':20 'dinosaur':2 ...">
おわりに
全 model で自動的にうまくテーブル名をつけたかったですが、今回はここまでです。
これを利用すれば、既存の DB に、Rails で接続して利用する時もできるようになりそう。
このサンプルデータは程よくデータが格納されているので、これでプライベートでも色々試せそうだなと思いました。
インゲージではエンジニアを募集中です!
詳細は以下のリンクよりご確認ください!