今まではrails db:migrate
を使用していましたが、学習する教材によっては
bundle exec rake db:migrate
としているので、コマンドがどのような意味を持っているのか調べてみました。
##まず、bundle
ってなに?
bundler
というGemを利用する際に使うコマンドです。
bundler
はGemの依存関係を解決するためのGemです。
Bundlerは、必要なgemとバージョンを正確に追跡してインストールすることにより、Rubyプロジェクトに一貫した環境を提供します。
Bundlerは依存関係の地獄からの出口であり、必要なGemが開発、ステージング、およびプロダクションに存在することを保証します。プロジェクトの作業を開始するのは簡単bundle installです。
bundlerの公式HPよりGoogle翻訳 https://bundler.io/
##exec
とは?
#####実行 【 execution 】 run / execute / exec / エグゼキューション
プログラムの実行のことは英語で “execute” (名詞形はexecution)と言い、 “exe” “exec” の略号で示されることもある。
それ自体がコンピュータ上で実行できる形式のプログラムファイルなどを「実行可能形式」(executable format)「実行可能ファイル」(executable file)などと言う。
また、プログラムを実行することを “run” (ラン:走る、走らせる)と表現することもあり、プログラムの実行時のことを「ランタイム」(runtime)という。日本語でも同様に「プログラムを走らせる」と言うことがある。
IT用語辞典 e-Words http://e-words.jp/w/%E5%AE%9F%E8%A1%8C.html
##ということは、bundle exec
の意味は?
bundle
でコマンドを実行すると宣言している。ということでしょうか。
パーフェクトRubyを見ると、
bundle exec
コマンドはbundle install
でインストールしたディレクトリに対してパスを解決し、コマンドを実行するためのプログラムです。
パーフェクトRuby【改定2版】Rubyサポーターズ著 技術評論社
とあります。
以下のBundler公式HPからの引用と合わせて考えると、bundle exec
はbundle install
したディレクトリを常に記憶しているから、installしたGemがどこにあろうが、bundle exec
しておけば気にしなくていいみたいです。
このコマンドを実行することで、Gemfile(5) で指定されたすべてのジェムを Ruby プログラムで要求できるようにします。
基本的には、通常は rspec spec/my_spec.rb のようなものを実行していて、Gemfile(5) で指定されたジェムを使用したい場合、 bundle install(1) でインストールしたものを bundle exec rspec spec/my_spec.rb を実行する必要があります。
bundle exec はシェルの $PATH に実行ファイルがある必要はないことに注意してください。
bundlerの公式HPよりDeepL翻訳 https://bundler.io/v2.0/man/bundle-exec.1.html
また、bundle exec
はrailsプロジェクト内のGemfile.lock
で指定された環境で実行されます。
Railsプロジェクト内でver.1
Railsプロジェクト外のグローバルシステムでver.2
の何かのGemを持っていた場合、以下のように実行されます。
bundle exec
がなければ、実行するGemのバージョンが異なる可能性が出てきます。
コマンド | 実行される環境 | バージョン |
---|---|---|
bundle exec | Railsプロジェクト | Ver.1 |
bundle execなし | マシン | Ver.2 |
##rake
とは
Gemです。Rubyで記述されたビルドツールで、Rakefile
と呼ばれるファイルに一連の処理をまとめた「タスク」を定義するというかたちで動作を記述します。
なお、ビルドツールとは自動化を想像するといいと思います。
一連の処理を記述したメソッドを実行するのと同じように、Rakeでは定義された「タスク」を実行します。
ちなみにRails5以降なら、rake
は不要みたいです。
Rakeとは
説明
Rubyで記述されたビルドツール
Rails5以降はrailsコマンドでrakeを呼び出せるようになっています
Railsドキュメント https://railsdoc.com/rake
ネットで調べるといつもrake
は不要という記事が多かったのですが、これで納得しました。
試しにrails6で、bundle exec rails db:migrate
を実行したら上手くいきました。
しかしrailsコマンドを使用するなら、bundle exec
はいらないような気がするのですが、どうなのでしょうか。
bundle exec
を使うと、railsプロジェクト内での環境で実行します。
では、rails
はrailsプロジェクト内での環境で実行してくれるのでしょうか。
rails
は、プロジェクトルートの bin/rails
を優先的に起動する仕様になっています。
そして、bin/rails
→config/boot
→bundler/setup
と読み込み実行されます。
bundler/setup
が実行されるとbundle exec
と同じ事が行われるので、結果としてrails
だけで十分のようです。
(ただ、私のプロジェクト内にはbundlerディレクトリが見つかりませんでした。)
##rake db:migrate
とは
rake
は、rake タスク名
で実行します。
今回のdb:migrate
のように、:
があるのは、複数のタスクがあるグループから、特定のタスクを取り出していることを示しています。
namespace :db
desc "説明文"
task :migrate do
処理を記述
end
end
##db:migrateの処理内容は?
Railsドキュメントから。
###未実行のマイグレーションファイルを実行
####使い方
$ rake db:migrate [VERSION=バージョン番号 オプション]
####実行の流れ
1 rake db:migrateを実行
2 schema_migrationsテーブルを調べ、存在しなければ作成
3 db/migrateディレクトリ内のすべてのマイグレーションファイルを調べる
4 データベースの現在のバージョンと異なるバージョンがあった場合、データベースに適応
5 schema_migrationsテーブルの更新
Railsドキュメント https://railsdoc.com/page/rake_db_migrate
##まとめ
bundle exec rake db:migrate
とは、インストールしたバージョンのGemを使用するためにbundle exec
し、rake db:migrate
で決められたタスクを実行している。
なお、rails5以降では、rails
コマンドでbunle exec
と同じ結果が得られる上、rake
タスクも呼び出せるため、rails db:migrate
でよさそう。
間違っていたらすみませんm(__)m
##参考
Rakeの理解に
http://rubicle.net/rubicle_talk_1-1.html
Bundlerの理解に
https://pikawaka.com/rails/bundler#bundler%E3%81%AE%E7%89%B9%E5%BE%B4