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
railsbinstub at ./bin/rails that should be used instead of the Bundler-generatedrailsbinstub.
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:binto add these executables to your own app.script/railsis 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
cdto 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 unicorngeneratesbin/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
--binstubsflag 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.rbis 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