はじめに

Rails で既存の DB を利用するアプリケーションの作り方を調べた。注意点としては、Rails からは DB の更新は行わず、読み込みのみ(Read Only)という構成である。

※最終的にはアクセスログなどのテーブルを更新することになると思うが、「アプリケーション本体の機能としては DB の更新はなし」(別のプログラムで DB が作られる)というイメージ。

TL;DR

  • DB 参照だけなら config/database.ymlapp/models/your_model.rb だけ作れば良い
  • db/schema.rbdb/migrate/xxxx.rb は不要
    • db/schema.rb あると、DB の構成確認できて便利かもね

目的・やったこと

冒頭に述べた通り、別プログラムで DB が作られているような構成で、ユーザー表示部分のみを Rails で提供したい場合の使い方を調べた。

rails_existing_db

目次

  1. はじめに
  2. TL;DR
  3. 目的・やったこと
  4. 環境・条件
  5. 詳細
    1. config/database.yml の設定
    2. app/models/your_model.rb の作成
    3. 【おまけ】rails db:schema:dump で db/schema.rb 作成
  6. まとめ
  7. その他・メモ
  8. 参考文献

環境・条件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.14.5
BuildVersion: 18F132

$ ruby --version
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin18]

$ bundle exec rails --version
Rails 5.2.3

$ rbenv --version
rbenv 1.1.2

$ gem --version
3.0.3

$ bundler --version
Bundler version 1.17.2

$ mysqld --version
mysqld Ver 5.7.26 for osx10.14 on x86_64 (Homebrew)

詳細

データベースの更新が不要(参照のみ)であれば、やることは2つのみ。

  1. config/database.yml の設定
  2. app/models/your_model.rb の作成

config/database.yml の設定

普通に Rails アプリケーションを作る時と同様に、既存 DB への接続に必要な情報(ユーザー名やパスワードなど)を設定すれば OK。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
default: &default
adapter: mysql2
encoding: utf8mb4
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: existing_username
password: existing_userpass
socket: /tmp/mysql.sock

development:
<<: *default
database: existing_db_development

test:
<<: *default
database: existing_db_test

production:
<<: *default
url: <%= ENV['EXISTING_DB_URL'] %>
database: existing_db_production
username: <%= ENV['EXISTING_DB_USER'] %>
password: <%= ENV['EXISTING_DB_PW'] %>

app/models/your_model.rb の作成

rails g modelrails g scaffold 実行時、--no-migration オプションを指定すればマイグレーションファイル(db/migrate/xxxx.rb)は作成されない。

1
2
3
4
5
6
7
$ rails g model hoge --no-migration
Running via Spring preloader in process 55995
invoke active_record
create app/models/hoge.rb
invoke test_unit
create test/models/hoge_test.rb
create test/fixtures/hoges.yml

ただし、rails g scaffold だと、(--no-resource-route オプションを付けても) newedit などの View ファイルも作成されてしまうため、必要な分だけ rails g modelrails g controller <actions> の方が良いと個人的には思った。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
$ be rails g scaffold fuga --no-migration
Running via Spring preloader in process 56064
invoke active_record
create app/models/fuga.rb
invoke test_unit
create test/models/fuga_test.rb
create test/fixtures/fugas.yml
invoke resource_route
route resources :fugas
invoke scaffold_controller
create app/controllers/fugas_controller.rb
invoke slim
create app/views/fugas
create app/views/fugas/index.html.slim
create app/views/fugas/edit.html.slim
create app/views/fugas/show.html.slim
create app/views/fugas/new.html.slim
create app/views/fugas/_form.html.slim
invoke test_unit
create test/controllers/fugas_controller_test.rb
create test/system/fugas_test.rb
invoke helper
create app/helpers/fugas_helper.rb
invoke test_unit
invoke jbuilder
create app/views/fugas/index.json.jbuilder
create app/views/fugas/show.json.jbuilder
create app/views/fugas/_fuga.json.jbuilder
invoke assets
invoke js
create app/assets/javascripts/fugas.js
invoke scss
create app/assets/stylesheets/fugas.scss
invoke scss
create app/assets/stylesheets/scaffolds.scss

Model ファイルが生成されたら、後はいつものようにアソシエーションなどを追加していけば良い。

1
2
3
4
5
6
7
class Hoge < ApplicationRecord
has_many :fugas
end

class fuga < ApplicationRecord
belongs_to :hoge
end

あとは ActiveRecord あたりがよしなにやってくれる(っぽい)。

1
2
3
4
5
6
7
8
9
$ rails c
Rails5.2.3 Ruby2.6.3 pry(main)> User.first
User Load (1.2ms) SELECT `users`.* FROM `users` ORDER BY `users`.`id` ASC LIMIT 1
+----+------+-------------------+------------------+
| id | name | updated_at | created_at |
+----+------+-------------------+------------------+
| 1 | foo | 2019-08-04 03:... | 2019-08-04 03... |
+----+------+-------------------+------------------+
1 row in set

【おまけ】rails db:schema:dumpdb/schema.rb 作成

既存 DB の情報を rails db:schema:dumpdb/schema.rb にダンプできる。

別にやらなくてもアクセスできるが、既存 DB の構成を確認したい場合にはあると便利かもしれない。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ rails db:schema:dump
# 何も出力されない
$ cat db/schema.rb
# This file is auto-generated from the current state of the database. Instead
# of editing this file, please use the migrations feature of Active Record to
# incrementally modify your database, and then regenerate this schema definition.
...
ActiveRecord::Schema.define(version: 0) do

create_table "users", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
t.string "name", null: false
t.datetime "updated_at", null: false
t.datetime "created_at", null: false
end
...
end

まとめ

  • DB 参照だけなら config/database.ymlapp/models/your_model.rb だけ作れば良い
  • db/schema.rbdb/migrate/xxxx.rb は不要
    • db/schema.rb あると、DB の構成確認できて便利かもね

その他・メモ

他システムを Rails に載せ替えとかの場合だと、新規作成や更新もあるだろうからマイグレーション必須だと思う。

ちなみに(当然なんだろうけど) DB にデータある状態で以下の操作を実行して、データをぶっ飛ばしたのでマイグレーションには注意しましょう。(自戒)

1
2
3
4
5
$ rails db:schema:dump
$ rails g migration create_tables
# db/schema.rb の内容を db/migrate/xxxx_create_tables.rb に移植
$ rails db:migrate
# ↑ ここでデータがぶっ飛ぶ(涙)

参考文献

関連記事