11
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Rails 5.2のマイグレーションファイルをSquasherで集約してみた

Last updated at Posted at 2019-01-20

前置き

モバイルアプリのバックエンドを学習を兼ねてRailsで開発しています。「マイグレーションファイルを統合出来ないかな」と思っていたところ、こちらの書籍にてSquasherが紹介されていたので、試してみました。

まずは現状を確認する

dbディレクトリに以下のマイグレーションファイルがあります。

$ tree
.
├── migrate
│   ├── 20181129152052_create_users.rb
│   ├── 20181129152325_add_column_to_users.rb
│   ├── 20181230120205_rename_column_device_token.rb
│   ├── 20181231084154_add_index_to_user.rb
│   ├── 20181231142632_create_devices.rb
│   ├── 20181231151529_add_reference_to_users.rb
│   ├── 20181231151946_add_reference_to_devices.rb
│   ├── 20190101175529_create_rooms.rb
│   ├── 20190101182417_create_talks.rb
│   ├── 20190101183525_add_reference_to_talks.rb
│   ├── 20190101183740_add_reference_to_rooms.rb
│   ├── 20190101184243_add_reference_talk_to_users.rb
│   ├── 20190101184438_add_reference_user_to_talks.rb
│   ├── 20190102101406_create_user_room_mappings.rb
│   ├── 20190102102554_add_index_to_user_room_mappings.rb
│   ├── 20190102133103_add_column_status_to_user_rooms_mappings.rb
│   ├── 20190102134153_rename_table_user_rooms_mappings_to_residence.rb
│   ├── 20190103102845_rename_table_residence_to_residences.rb
│   ├── 20190103140215_add_reference_rooms_to_user.rb
│   ├── 20190103140817_add_reference_users_to_room.rb
│   ├── 20190103144721_rename_column_user_id_to_users.rb
│   ├── 20190109141322_rename_column_capacity_posts_par_user_to_rooms.rb
│   ├── 20190119135319_rename_column_capacity_users_to_rooms.rb
│   ├── 20190119135359_rename_column_capacity_post_per_user_to_rooms.rb
│   ├── 20190119143121_add_column_lifetime_to_rooms.rb
│   ├── 20190119143654_del_column_name_to_rooms.rb
│   ├── 20190119145901_del_reference_from_users.rb
│   └── 20190119150920_del_reference_to_rooms.rb
├── schema.rb
└── seeds.rb

インストールする

基本的には公式に沿って進めていきます。

  1. GemfileにSquasherを追記します

    Gemfile

source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '2.5.1'

gem 'rails', '~> 5.2.2'
gem 'mysql2', '>= 0.4.4', '< 0.6.0'
gem 'puma', '~> 3.11'
gem 'bootsnap', '>= 1.1.0', require: false
gem 'config', '~> 1.7.0'
gem 'jwt', '~> 2.1.0'

group :development, :test do
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
  gem 'rspec-rails'
  gem 'factory_bot_rails'

end

group :development do
  gem 'listen', '>= 3.0.5', '< 3.2'
  gem 'spring'
  gem 'spring-watcher-listen', '~> 2.0.0'
  gem 'rubocop', '~> 0.60.0', require: false

end

# --- Squasherに関するGemを追加 ここから
group :tools do
  gem 'squasher', '>= 0.6.0'
  gem 'capistrano'
  # gem 'rubocop'  当プロジェクトでは既に導入しているので除外

end
# --- Squasherに関するGemを追加 ここまで

gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
1. Gemをインストールします

    ```
# bundle install
Fetching gem metadata from https://rubygems.org/.........
Fetching gem metadata from https://rubygems.org/.
Resolving dependencies...
        :
Fetching squasher 0.6.2
Installing squasher 0.6.2
Bundle complete! 16 Gemfile dependencies, 87 gems now installed.
Bundled gems are installed into `./vendor/bundle`
  1. Squacherを導入します

bundle binstub squasher

bin/squasher

Your bin/bundle was not generated by Bundler, so this binstub cannot run.
Replace bin/bundle by running bundle binstubs bundler --force, then run this command again.

環境の違いからか`bundle binstubs bundler --force`するよう求められました。無事に利用可能になりました:thumbsup:

    ```
# bundle binstubs bundler --force
# bin/squasher
Squasher 0.6.2

実行する

  1. squasherコマンドの実行します
    「○○より前のマイグレーションファイルを集約する」という指示の仕方になります。今までのマイグレーションファイルを全て集約することにしますので2020年を指定します。Rails 5.2を利用しているのでmオプションの引数に5.2を指定します。

bin/squasher 2020 -m 5.2

Squasher is creating a tmp database
Dropped database 'squasher'
Created database 'squasher'
Squasher is applying migrations on a tmp database
== 20181129152052 CreateUsers: migrating ======================================
-- create_table(:users)
-> 0.0317s
== 20181129152052 CreateUsers: migrated (0.0319s) =============================
:
== 20190119150920 DelReferenceToRooms: migrating ==============================
-- remove_reference(:rooms, :talk, {:foreign_key=>true})
-> 0.0932s
== 20190119150920 DelReferenceToRooms: migrated (0.0934s) =====================

1. SquasherのDBの削除やクリーンの可否を選択します

    ```
Squasher's created the `squasher` database for its needs.
It might be useful to keep it if any of your deleted migrations inserts data or
you squash migrations in a few steps (look at -r option).
Keep it (yes / no)?
yes     # デフォルト
```

Do you want to clean your database from the old schema migration records(yes/no)?
no # デフォルト


# 実行後のマイグレーションファイルを確認する
集約されたことがわかります。

$ tree
.
├── migrate
│   └── 20190119150920_init_schema.rb
├── schema.rb
└── seeds.rb


# 再構築してみる
集約されたマイグレーションファイルでDBを再構築してみます。

```bash
$ bundle exec rails db:drop
Dropped database 'app_development'
Dropped database 'app_test'

$ bundle exec rails db:create
Created database 'app_development'
Created database 'app_test'

$ bundle exec rails db:migrate
== 20190119150920 InitSchema: migrating =======================================
-- create_table("devices", {:options=>"ENGINE=InnoDB DEFAULT CHARSET=utf8"})
   -> 0.0399s
    :
-- add_foreign_key("talks", "users")
   -> 0.0749s
== 20190119150920 InitSchema: migrated (0.4857s) ==============================

補足(失敗談)

Rails5.2では公式の手順をコピペしてmオプションに5.0を指定すると再構築でエラーが発生します。

# bin/squasher 2020 -m 5.0

Rails5.0ではデフォルトで作成されるidカラムはint型で、Rails5.1以降で作成されるidカラムはbigint型です。Rails5.2で作成された主キーと外部キーの関係はbigint型が前提となっているので、このようなエラーが発生します。

$ bundle exec rails db:migrate
== 20190119150920 InitSchema: migrating =======================================
-- adapter_name()
   -> 0.0000s
    :
-- add_foreign_key("devices", "users")
rails aborted!
StandardError: An error has occurred, all later migrations canceled:

Column `user_id` on table `devices` has a type of `bigint(20)`.
This does not match column `id` on `users`, which has type `int(11)`.
To resolve this issue, change the type of the `user_id` column on `devices` to be :integer. (For example `t.integer user_id`).
    :
bin/rails:4:in `<main>'
Tasks: TOP => db:migrate
(See full trace by running task with --trace)

mオプションで継承するActiveRecord::Migrationのバージョンが変わるようですね。

mオプション 継承元
5.0 class InitSchema < ActiveRecord::Migration[5.0]
5.2 class InitSchema < ActiveRecord::Migration[5.2]

終わりに

先述の失敗談で少しハマりましたが、目的を達成することは出来ました。特にカラム名のtypoを修正するマイグレーションファイルなどは集約されスッキリしてよかったです。

11
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?