Say I have a Rails app with gems installed with bundler
. Should I use bundle exec rails
or bin/rails
? Should I use bundle exec rake
or bin/rake
? Is there any difference? Is any of those better then the other one?
tl;dr no particular difference, but if I were to choose, I'd use bin/rails
There's little to no difference. Let us see.
DISABLE_SPRING=1 bin/rails --version
:
bin/rails
: require_relative '../config/boot'
config/boot
: require 'bundler/setup'
bundler/setup
: Bundler.setup
Bundler.setup
: definition.validate_runtime!
Bundler.definition
: Definition.build
Bundler::Definition.build
: Dsl.evaluate
Bundler::Dsl.evaluate
: builder.eval_gemfile
Bundler::Dsl#eval_gemfile
: instance_eval
After require 'bundler/setup'
, trying to gem 'rails', 'x.y.z'
results in:
*** Gem::LoadError Exception: can't activate rails (= x.y.z), already activated rails-5.1.3. Make sure all dependencies are added to Gemfile.
With bundle exec rails --version
, we end up running bin/rails
anyway:
~/.gem/ruby/x.y.z/bin/rails
: load Gem.activate_bin_path('railties', 'rails', version)
exe/rails
: require 'rails/cli'
rails/cli
: Rails::AppLoader.exec_app
Rails::AppLoader.exec_app
: `exec RUBY, 'bin/rails', *ARGV
Also, do note the message one can found in the last file:
Beginning in Rails 4, Rails ships with a
rails
binstub at ./bin/rails that should be used instead of the Bundler-generatedrails
binstub.
So, at the end of the day there's no difference. But considering the fact that Rails goes through the trouble of shipping its own binstubs, I'd favor bin/rails
alternative. Also, it autocompletes better.
And,
App executables now live in the
bin/
directory:bin/bundle
,bin/rails
,bin/rake
. Runrake rails:update:bin
to add these executables to your own app.script/rails
is gone from new apps.Running executables within your app ensures they use your app's Ruby version and its bundled gems, and it ensures your production deployment tools only need to execute a single script. No more having to carefully
cd
to the app dir and runbundle exec ...
.Rather than treating
bin/
as a junk drawer for generated "binstubs", bundler 1.3 adds support for generating stubs for just the executables you actually use:bundle binstubs unicorn
generatesbin/unicorn
. Add that executable to git and version it just like any other app code.
https://github.com/rails/rails/blob/4-0-stable/railties/CHANGELOG.md
bundle exec
just ensures that all gems in Gemfile are installed (globally or on userspace or in vendor/bundle
directory of the project) when running the command. It's explained in more detail in https://bundler.io/man/bundle-exec.1.html (especifically https://bundler.io/man/bundle-exec.1.html#BUNDLE-INSTALL-BINSTUBS section):
Bundle Install --binstubs
If you use the
--binstubs
flag inbundle install
, Bundler will automatically create a directory (which defaults toapp_root/bin
) containing all of the executables available from gems in the bundle.After using
--binstubs
,bin/rspec spec/my_spec.rb
is identical tobundle exec rspec spec/my_spec.rb
.
Binstubs may also include other customizations like loading spring
gem, which preloads and speeds up the Rails application.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With