bundle exec rake db:migrate
はどういう意味ですか?それとも単にbundle exec rake <command>
だけ?
私はbundle
がGemfileの中のものを維持することに気を配っていることを理解しています。 「exec」という言葉の意味を知っています。私はrake
があなたができるすべての異なったスクリプトのことを維持していることを理解しています、そして私はdb:migrate
がそれらのうちの1つであることを知っています。これらすべての言葉が一体となって何をしているのか私にはわかりません。データベース移行を実行するためにbundle
を実行するのにrake
を使用する必要があるのはなぜですか?
bundle exec
は現在のバンドルのコンテキストでスクリプトを実行する Bundler コマンドです(ディレクトリの Gemfile からのもの)。 rake db:migrate
はdbがネームスペースで、migrateがタスクであるスクリプトです。定義された名前.
そのため、bundle exec rake db:migrate
は現在のバンドルのコンテキストでコマンドdb:migrate
を使ってrakeスクリプトを実行します。
「なぜ」 バンドラーページ から引用します。
場合によっては、実行可能ファイルがシステムにインストールされていて、バンドルと競合するgemを引き込まないのであれば、
bundle exec
を指定せずに実行可能ファイルを実行してもうまくいくことがあります。しかし、これは信頼性が低く、かなりの痛みの原因となります。動作しているように見えても、将来または他のマシンで動作しなくなる可能性があります。
あなたはプログラムでbundle exec
を実行しています。プログラムの作成者は、特定のバージョンのgemが利用可能になったときにそれを書きました。 Gemfileプログラムは、作成者が使用することを決めたgemのバージョンを指定します。つまり、スクリプトはこれらのgemバージョンに対して正しく動作するように作られています。
システム全体のGemfileはこのGemfileと異なる場合があります。このスクリプトがうまく動作しない、より新しいまたはより古いgemがあるかもしれません。バージョンのこの違いはあなたに奇妙なエラーを与える可能性があります。
Bundle exec
は、これらのエラーを回避するのに役立ちます。システム全体のGemfileではなく、スクリプトのGemfileで指定されたgemを使ってスクリプトを実行します。それはシェルエイリアスの魔法で特定のgemバージョンを実行します。
manページ の詳細を見てください。
これがGemfileの例です。
source 'http://rubygems.org'
gem 'Rails', '2.8.3'
ここで、bundle exec
はRailsバージョン2.8.3を使用してスクリプトを実行しますが、システム全体にインストールされている可能性がある他のバージョンは使用しません。
あなたのgemfile.lockがあなたのマシンにインストールされているgemの異なるバージョンを持っているとき、これは大いに起こります。次のようにrake(またはrspecなど)を実行した後に警告が表示されることがあります。
You have already activated rake 10.3.1, but your Gemfile requires rake 10.1.0. Prepending "bundle exec" to your command may solve this.
bundle exec
を前に付けると、バージョンの違いにかかわらずこのコマンドを実行するようにバンドラーに指示します。常に問題があるわけではありませんが、問題が発生する可能性があります。
幸いなことに、これを解決する宝石があります:rubygems-bundler。
$ gem install rubygems-bundler
$ $ gem regenerate_binstubs
それからあなたの熊手、rspec、または何でも試してみてください。
bundle exec
を省略する方法があることはおそらく言及されるべきです(それらはすべてMichael Hartlsの3.6.1章 Ruby on Railsチュートリアル bookに述べられています)。
最も簡単なのは、RVMの十分に最新のバージョン(> = 1.11.x)を使用することです。
以前のバージョンのRVMに限定している場合は、 calasyr でも言及されているこの方法をいつでも使用できます。
$ rvm get head && rvm reload
$ chmod +x $rvm_path/hooks/after_cd_bundler
$ bundle install --binstubs=./bundler_stubs
bundler_stubs
ディレクトリも.gitignore
ファイルに追加する必要があります。
RVMを使用していない場合は、3番目の方法としてrubygems-bundler
gemを使用します。
$ gem install rubygems-bundler
$ gem regenerate_binstubs
私はbundle execをあまり使っていませんが、今それを設定しています。
間違ったレーキが使用され、問題を突き止めるのに多くの時間が費やされた事例がありました。これはあなたがそれを避けるのを助けます。
特定のプロジェクトディレクトリ内でデフォルトでbundle execを使用できるように、rvmを設定する方法は次のとおりです。
http://robots.thoughtbot.com/post/15346721484/use-bundlers-binstubs
Rakeタスクを直接実行したり、gemのバイナリファイルを実行したりしても、コマンドが期待どおりに動作するとは限りません。なぜなら、あなたはすでに同じgemがあなたのシステムにインストールされていて、それらはバージョン1.0と言っていますが、あなたのプロジェクトではあなたはより高いバージョンが2.0と言っているのです。この場合、どちらが使用されるのか予測できません。
目的のgemバージョンを強制するには、現在のバンドルのコンテキストでバイナリを実行するbundle exec
コマンドを使用します。つまり、bundle execを使用すると、bundlerは現在のプロジェクトに設定されているgemのバージョンを確認し、それを使用してタスクを実行します。
私はそれについて ポスト も書いています。これはビンスタブを使ってそれを使わないようにする方法も示しています。
これは、バンドラーが認識していないこと、およびdb:migrateタスクを実行して実行していることを意味します。