Question

I'm trying to follow along the "Getting Started with Engines" Rails Guide's tutorial and found this:

$ bin/rails plugin new blorgh --mountable

When I type this on my terminal, I get:

bash: bin/rails: No such file or directory

When I try just $ rails it works OK.

I've been using the command line for a couple of months, and Rails as well. I know the $ sign but I'm confused about the meaning of the "bin" after that. I'm used to type "Rails" right after $, but this tutorial says that use "bin" ...

What does bin/ mean?

Was it helpful?

Solution

tl;dr

Run bundle install --binstubs and it'll work. You only have to do it once and Bundler will remember that you asked for it (for that project).

Longer answer

When you install a bundle with bundle --binstubs, Bundler will install all your bundle-specific binstubs into the bin/ subdirectory (relative to the Gemfile), rather than putting them into the gemset's global binstub paths.

You would typically do this to:

  1. Ensure that the rails binstub you're running is the one in your Gemfile (as opposed to a different version that got installed into your gemset later, separate from Bundler), and
  2. To improve execution time (since it's functionally equivalent to bundle exec rails except minus one subprocess invocation).

Global binstubs vs Bundler binstubs

If you type which rails, you will get a long path like /usr/local/rvm/gems/jruby-1.7.18/bin/rails, and the contents of which: cat `which rails`

#!/usr/bin/env jruby_executable_hooks
#
# This file was generated by RubyGems.
#
# The application 'railties' is installed as part of a gem, and
# this file is here to facilitate running it.
#

require 'rubygems'

version = ">= 0"

if ARGV.first
  str = ARGV.first
  str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
  if str =~ /\A_(.*)_\z/
    version = $1
    ARGV.shift
  end
end

gem 'railties', version
load Gem.bin_path('railties', 'rails', version)

After running bundler --binstubs, if you cat bin/rails, you'll get something like:

#!/usr/bin/env jruby
#
# This file was generated by Bundler.
#
# The application 'rails' is installed as part of a gem, and
# this file is here to facilitate running it.
#

require 'pathname'
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
  Pathname.new(__FILE__).realpath)

require 'rubygems'
require 'bundler/setup'

load Gem.bin_path('railties', 'rails')

The key difference there is that the bin/ version sets the BUNDLE_GEMFILE environment variable, and it requires bundler/setup, which is what tells Bundler to go do its thing with gem paths. The bin/rails script is bundler-aware, and is aware of your Gemfile, so it can prepare your environment right off the bat.

I generally recommend using --binstubs and bin/x invocations over the gemset versions.

OTHER TIPS

Consider this scenario:

I had an app that was using Rails version 4.0.0. My goal was to upgrade it to Rails 4.1.9. To do so, I tried to upgrade it step by step: first, upgrading to 4.0.13, then 4.1 and finally 4.1.9.

Everything went smoothly. All the tests were passing using RSpec.

Finally, I tried to run my server with rails s. Booom! Ruby crashed. Then, I used bin/rails s. Everything went ok.

So I think if you have different version of rails set up in your system, it's safer to use bin/rails option.

P.S. To make sure that my assumption is correct, I removed all rails version except 4.1.9 and then I tried to rerun the server with rails s. No crash this time.

Hope this clarifies.

When you run an executable via shell in a unix-based operating system, your system path will be searched first. To see all of the directories in your $PATH, try this from your terminal prompt:

echo $PATH

the rails executable will be present in one of the listed directories.

Edit - The text below is completely wrong, my apologies

Optionally, from the root of your rails directory, you can run the executable in the bin directory. To do this, that is, to ensure you're running the local executable and not one found in your $PATH, you need a '.' before the command. So,

./bin/rails

not

bin/rails

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top