[Ruby on Rails 4] Factory Girl から Factory Bot へ移行する

遅ればせながらイントラツールの移行をしました memo.

公式と @jnchito さんの記事を参考にして進めました。

> – [factory_bot/UPGRADE_FROM_FACTORY_GIRL.md at 4-9-0-stable · thoughtbot/factory_bot](https://github.com/thoughtbot/factory_bot/blob/4-9-0-stable/UPGRADE_FROM_FACTORY_GIRL.md)
> – [【翻訳】”Factory Girl”が”Factory Bot”に変わった理由(と移行手順) – Qiita](https://qiita.com/jnchito/items/c71b8f66f61214227555)

## Gemfileを更新してbundle install

GemFile を更新します。

“`ruby:GemFile
group :development, :test do
gem ‘factory_bot_rails’
“`

`bundle install` を実行します。

## プロジェクト内の FactoryGirl を FactoryBot に置換

grep と sed で一括置換します。
が、`argument list too long: grep` とエラー。

“`prettyprinted
% grep -e FactoryGirl **/*.rake **/*.rb -s -l | xargs sed -i “” “s|FactoryGirl|FactoryBot|g”
zsh: argument list too long: grep
“`

公式サイトの “various other approaches” を確認してコマンドを少し修正しました。

> – [Update UPGRADE_FROM_FACTORY_GIRL.md by diei · Pull Request #1084 · thoughtbot/factory_bot](https://github.com/thoughtbot/factory_bot/pull/1084)

“`prettyprinted
% grep -rl -e FactoryGirl –include=\*.{rb,rake} . | xargs sed -i “” “s|FactoryGirl|FactoryBot|g”
“`

## プロジェクト内の factory_girl を factory_bot に置換

Opps!

“`prettyprinted
% grep -e factory_girl **/*.rake **/*.rb -s -l | xargs sed -i “” “s|factory_girl|factory_bot|g”
zsh: argument list too long: grep
“`

書き換えて実行します。

“`prettyprinted
% grep -rl -e factory_girl –include=\*.{rb,rake} . | xargs sed -i “” “s|factory_girl|factory_bot|g”
“`

## テストがすべてパスすることを確認

テストを実行。

“`prettyprinted
% bin/rake spec
:
An error occurred while loading ./spec/routing/foo_spec.rb.
Failure/Error: weight 2

NoMethodError:
undefined method ‘weight’ in ‘delivery_charge’ factory
Did you mean? ‘weight { 2 }’
:
0 examples, 0 failures, 21 errors occurred outside of examples
“`

エラーが発生したので修正。
`spec/factories/*.rb` 内のファイルを指示通り `{ }` 付きに修正。

いろいろあって触れていなかったけれども、地道にアップグレードしていく。

## 補遺

実行したコマンドのオプションについて。

“`prettyprinted
% grep -rl -e FactoryGirl –include=\*.{rb,rake} . | xargs sed -i “” “s|FactoryGirl|FactoryBot|g”
“`

`grep`

> -r –recursive ディレクトリを指定した場合はサブディレクトリ内のファイルも含めて検索する(–directories=recurse相当)
>
> [【 grep 】コマンド――特定の文字を含む行を抽出する:Linux基本コマンドTips(9) – @IT](https://www.atmarkit.co.jp/ait/articles/1604/07/news018.html)

`sed`

> 最後のスラッシュの後に付加されている ‘g’ オプションが一括置換を指示しています。
>
> [共通テーマ: 実例でわかる sed 第 2 回](https://www.ibm.com/developerworks/jp/linux/library/l-sed2/index.html)