rbenv ruby on rails global vs local vs shell - ruby-on-rails

// Start background info.
I just want to install ruby on rails for development (OSX El Capitan).
Pain point:
ERROR: While executing gem ... (Gem::FilePermissionError)
You don't have write permissions for the /Library/Ruby/Gems/2.0.0 directory.
Solution: Installed rbenv to manage / modify a separate ruby.
rbenv is currently using my system ruby - so I've downloaded an identical version through rbenv install.
// end background info.
Actual Question: Do I set rbenv local, global or shell ruby version to the newly downloaded version?

Usually rbenv does the dirty work for you if loaded correctly, but if you need to change the global setting, you can always update it:
rbenv global 2.3.0
Then you can check that's properly applied with:
rbenv versions
The * indicates the currently active ruby. Test with:
ruby -v
That should be the version you're asking for.
Using rbenv is a lot better than the system ruby, so I hope it works out for you.

According to the official rbenv documentation in Github, their differences are the following:
# Sets a local application-specific Ruby version
# by writing the version name to a `.ruby-version`.
$ rbenv local <version>
# Sets the global version of Ruby to be used in all shells
# by writing the version name to the `~/.rbenv/version` file
$ rbenv global <version>
# Sets a shell-specific Ruby version by setting the
# RBENV_VERSION environment variable in your shell.
# This for temporary use and will only work during the terminal session
$ rbenv shell <version>
Note that your terminal session will no longer respect any .ruby-version files. You need to run rbenv shell --unset to enable the auto switch again.
Happy Coding :)

Related

Terminal closed and I can't access the rails server anymore

I have a rails application that I have been working on for a few days after I successfully installed rails.
I closed my terminal window to open up a new window and unfortunately when I try to restart the local rails server, it says rails is no longer able to be found.
Even after I run 
rbenv install 3.1.2
the ruby version does not reflect the latest.
Installing ruby-3.1.2...ruby-build: using readline from homebrewInstalled ruby-3.1.2 to /Users/sharatakasapu/.rbenv/versions/3.1.2
Sharats-MBP:~ sharatakasapu$ ruby -vruby 2.6.8p205 (2021-07-07 revision 67951) [universal.x86_64-darwin21]Sharats-MBP:~ sharatakasapu$ 
When I try to install rails
gem install rails -v 7.0.2.4
I get this error
ERROR:  While executing gem ... (Gem::FilePermissionError)    You don't have write permissions for the /Library/Ruby/Gems/2.6.0 directory.
This doesn't exactly seem like a ruby question so much as a macOS question. You used rbenv to upgrade your ruby which is fine, but macOs currently comes with ruby 2.6 pre-installed. Your system probably has it installed for a reason so don't remove it.
Try running which ruby in your shell to confirm your shell is picking up /usr/bin/ruby which is the built in version. To pick up a different version of ruby you'll need to modify your system path so that the location of the ruby version you want to pick up gets scanned before the version you don't want.
You will first need to find where rbenv installed the ruby version you are looking for on your machine. The output you sent says rbenv to ~/.rbenv/versions/3.1.2. You can modify the path variable of a single shell session with PATH=$HOME/.rbenv/versions/3.1.2:$PATH but this is imperfect because if you close the shell and reopen it your path will have its prior value. I've certainly made that mistake before.
Persistently changing your path depends on your shell version but the default shell on macOS is zsh which can be configured by appending export PATH=$HOME/.rbenv/versions/3.1.2:$PATH" to your .zshenv you may have to research your specific shell. You'll know you did it right when which ruby brings up the location of the new ruby and ruby --version returns the expected version. Cheers.
echo 'if which rbenv > /dev/null; then eval "$(rbenv init -)"; fi' >> ~/.zshrc
source ~/.zshrc
You are using the ruby version of your system, not the rbenv one. Follow the next steps to switch to rbenv.
Step 1 Add the following lines to your .zshrc file if they are not exist
export PATH="$HOME/.rbenv/bin:$PATH"
eval "$(rbenv init - zsh)"
Step 2
rbenv install 3.1.2
rbenv global 3.1.2
Step 3
gem install rails -v 7.0.2.4

Two different ruby versions on mac?

I am setting up a simple ruby on rails app locally. It seems I have two different versions of ruby on mac and I would like to only use one. When I ran bundle install, it says Your Ruby version is 2.7.1, but your Gemfile specified 2.6.3. Then, I changed the line ruby '2.6.3' in my gemfile to ruby '2.7.1'. With this it ran bundle install properly. However, when I run rails server it says Your Ruby version is 2.6.3, but your Gemfile specified 2.7.1.
Why is it saying two different values for my Ruby version?
How do I get it to only use one version of Ruby?
If its relevant, I am on a mac and installed ruby using homebrew. If I run ruby -v in the terminal it says ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-darwin19]. I'm not sure why it says I have ruby 2.6.3.
There are to different versions because Mac OSX already includes one by default for system scripts (2.6). Homebrew install another one that never overrides o reemplace the System Wide version.
You are looking for a "Ruby Version Manager", are tools that allow you to install and use different versions of Ruby, even per project.
The popular ones are RVM and rbenv. Personally, i choose rbenv and I think that is the most widely used of both. Example of use:
# Install ruby 2.7
rbenv install 2.7.1
# Make ruby 2.7 the default version
$ rbenv global 2.7.1
# Or make 2.7 the default versión only on a specific project
$ cd myproject
$ rbenv local 2.7.1
# this create a ".ruby-version" file
This webpage always have the most recent and easy to use tutorial for setup a Ruby environment, depending on the OS and version.
https://gorails.com/setup/osx/10.15-catalina#overview
You have two different versions of Ruby installed, because MacOS natively comes with a standard installation of Ruby.
You also have rails pointing to the system version of Ruby. That version is usually under /usr/bin/ruby. The Homebrew installed version of Ruby (which is what you want) is located under /usr/local/bin/ruby unless you specified a completely different root path to install your brew packages.
Running brew config will give you a short list of data about your Homebrew configuration. Among them is an environment variable called HOMEBREW_PREFIX, which should look something like this:
$ brew config
....
HOMEBREW_PREFIX: /usr/local
....
I recommend placing /usr/local/bin first on your PATH environment variable so that you can easily use your brew packages via the CLI:
export PATH="/usr/local/bin:$PATH"
You may also want to look into setting the following environment variables for whichever shell you are using (examples given):
RUBY_ENGINE=ruby
RUBY_VERSION=2.7.1
GEM_ROOT=/usr/local/etc/ruby-2.7.1/lib/ruby/gems/2.7.1 (alias for GEM_HOME)
gem env gives a lot of great information on how Gems is configured.
I I had this exact problem and managed to fix it by running this command:
CFLAGS="-Wno-error=implicit-function-declaration" rbenv install 2.6.7
Note - I needed that version (2.6.7) please change it to the one you need
I found this on this blog post here - https://dev.to/rbazinet/fix-installation-of-ruby-using-rbenv-on-macos-big-sur-3432

RVM's current and default version isn't actually being used

I am running my rails app from a virtualbox build by vagrant using puppet scripts. Every time I login to the box, I have the following problem:
When I run rvm list one of the things it lists is the following:
=* ruby-2.1.1
But when I try to run rails console, it tells me I need to install missing gems. When I run rvm use default, and then run rails console, it works. Why is the default and current setting in rvm not working--why do I have to go to the extra step of also telling rvm which ruby version to use?
Note: I do have a .ruby-version file with 2.1.1 in it. I'm using rvm version 1.25.25
Because you have to tell rvm which version to use.
In earlier version of rvm we have to define .rvmrc file which mention which ruby and gemset to use.
In recent version of rvm we have to define .ruby-version file with ruby version in it and .ruby-gemset file with the name of gemset.
If you just want a quick solution then in your rails directory make a .ruby-version file with content 2.1.1
correct syntax is:
rvm --default use ruby-2.1.1#global
This command sets ruby to selected default permanently. All new terminals will use your default Ruby. Also you don't mention anything about gemset, so I presume global would exist if you didn't mess up your setup.
This solved it:
I added rvm use --default to the machine's ~/.bashrc file.

How do RVM and rbenv actually work?

I am interested in how RVM and rbenv actually work.
Obviously they swap between different versions of Ruby and gemsets, but how is this achieved? I had assumed they were simply updating symlinks, but having delved into the code (and I must admit my knowledge of Bash is superficial) they appear to be doing more than this.
Short explanation: rbenv works by hooking into your environment's PATH. The concept is simple, but the devil is in the details; full scoop below.
First, rbenv creates shims for all the commands (ruby, irb, rake, gem and so on) across all your installed versions of Ruby. This process is called rehashing. Every time you install a new version of Ruby or install a gem that provides a command, run rbenv rehash to make sure any new commands are shimmed.
These shims live in a single directory (~/.rbenv/shims by default). To use rbenv, you need only add the shims directory to the front of your PATH:
export PATH="$HOME/.rbenv/shims:$PATH"
Then any time you run ruby from the command line, or run a script whose shebang reads #!/usr/bin/env ruby, your operating system will find ~/.rbenv/shims/ruby first and run it instead of any other ruby executable you may have installed.
Each shim is a tiny Bash script that in turn runs rbenv exec. So with rbenv in your path, irb is equivalent to rbenv exec irb, and ruby -e "puts 42" is equivalent to rbenv exec ruby -e "puts 42".
The rbenv exec command figures out what version of Ruby you want to use, then runs the corresponding command for that version. Here's how:
If the RBENV_VERSION environment variable is set, its value determines the version of Ruby to use.
If the current working directory has an .rbenv-version file, its contents are used to set the RBENV_VERSION environment variable.
If there is no .rbenv-version file in the current directory, rbenv searches each parent directory for an .rbenv-version file until it hits the root of your filesystem. If one is found, its contents are used to set the RBENV_VERSION environment variable.
If RBENV_VERSION is still not set, rbenv tries to set it using the contents of the ~/.rbenv/version file.
If no version is specified anywhere, rbenv assumes you want to use the "system" Ruby—i.e. whatever version would be run if rbenv weren't in your path.
(You can set a project-specific Ruby version with the rbenv local command, which creates a .rbenv-version file in the current directory. Similarly, the rbenv global command modifies the ~/.rbenv/version file.)
Armed with an RBENV_VERSION environment variable, rbenv adds ~/.rbenv/versions/$RBENV_VERSION/bin to the front of your PATH, then execs the command and arguments passed to rbenv exec. Voila!
For a thorough look at exactly what happens under the hood, try setting RBENV_DEBUG=1 and running a Ruby command. Every Bash command that rbenv runs will be written to your terminal.
Now, rbenv is just concerned with switching versions, but a thriving ecosystem of plugins will help you do everything from installing Ruby to setting up your environment, managing "gemsets" and even automating bundle exec.
I am not quite sure what IRC support has to do with switching Ruby versions, and rbenv is designed to be simple and understandable enough not to require support. But should you ever need help, the issue tracker and Twitter are just a couple of clicks away.
Disclosure: I am the author of rbenv, ruby-build, and rbenv-vars.
I wrote an in-depth article: http://niczsoft.com/2011/11/what-you-should-know-about-rbenv-and-rvm/
The basic difference is where the shell environment is changed:
RVM: it's changed when you change Ruby.
rbenv: it's changed when you run a Ruby/gem executable.
Also, the thing about RVM is, it covers a lot more then just managing Rubies, it has a lot more than any other tool (there are others apart from RVM and rbenv: https://twitter.com/#!/mpapis/status/171714447910502401)
Do not forget about instant support you get on IRC in the "#rvm" channel on the Freenode servers.
So to summarise the excellent answers above, the main practical difference between RVM and rbenv is when the version of Ruby is selected.
rbenv:
rbenv adds a shim to the start of your path, a command with the same name as Ruby. When you type ruby at a command line the shim is run instead (because it is also called "ruby" and comes first in the path). The shim looks for an environment variable or .rbenv_version file to tell it which version of Ruby to delegate to.
RVM:
RVM allows you to set a version of Ruby directly by calling rvm use. In addition, it also overrides the cd system command. When you cd into a folder that contains a .rvmrc file, the code inside the .rvmrc file is executed. This can be used to set a Ruby version, or anything else you fancy.
Other differences:
There are of course other differences. RVM has gemsets out of the box, while rbenv requires just a little more hacking (but not much). Both are functional solutions to the problem.
The main difference seems to be when and how ruby is switched. Ruby is switched:
for RVM manually (rvm use) or automatically during change of directories
for rbenv automatically each time a ruby command is executed
RVM relies on the modified cd command and manual selection of Ruby by rvm use. rbenv uses wrappers or "shims" for all basic ruby commands as the default mechanism to select ruby. RVM creates wrappers for basic command line tools like gem, rake, ruby, too. They are used for example in CronJobs ( see http://rvm.io/integration/cron/ ), but they are not the default mechanism to switch the Ruby version.
Thus both methods select "automatically" the right Ruby version by overwriting commands and using wrappers. rvm overrides shell commands like cd. rbenv overrides all basic ruby commands such as ruby, irb, rake and gem.
rvm system
env > before
rvm jruby # or whatever
env > after
diff after before
Gives you approximately:
< GEM_HOME=$HOME/.gem/ruby/1.9.1
---
> GEM_HOME=$HOME/.rvm/gems/jruby-1.6.6
< GEM_PATH=$HOME/.gem/ruby/1.9.1
---
> GEM_PATH=$HOME/.rvm/gems/jruby-1.6.6:$HOME/.rvm/gems/jruby-1.6.6#global
*bunch of rvm_*
> MY_RUBY_HOME=$HOME/.rvm/rubies/jruby-1.6.6
> RUBY_VERSION=jruby-1.6.6
> IRBRC=$HOME/.rvm/rubies/jruby-1.6.6/.irbrc
And it prepends:
$HOME/.rvm/gems/jruby-1.6.6/bin:$HOME/.rvm/gems/jruby-1.6.6#global/bin
to $PATH

How do you use multiple rails versions with rbenv?

Is it possible to use multiple versions of rails using rbenv (e.g. 2.3 and 3.1)? This was easy with gemsets in rvm, but I'm wondering what the best way is to do it now that I've switched to rbenv (also, I'm looking for a way to do it without rbenv-gemset).
not sure if you got an answer to this, but I thought I'd offer what I did and it seemed to work.
So once you get rbenv installed, and you use it to install a specific ruby version, you can install multiple versions of rails to for that ruby.
STEP 1. Install whatever version(s) of rails you want per ruby version
% RBENV_VERSION=1.9.2-p290 rbenv exec gem install rails --version 3.0.11
By using the "RBENV_VERSION=1.9.2-p290" prefix in your command line, you're specifying which ruby rbenv should be concerned with.
Then following that with the "rbenv exec" command, you can install rails. Just use the version flag as in the example to specify which version you want. Not sure if you can install multiple versions in one shot, but I just run this command as many times as needed to install each version I want.
Note: This will all be managed within your rbenv directory, so it's perfectly safe and contained.
STEP 2. Build a new rails project by specifying the rails version you want.
% RBENV_VERSION=1.9.2-p290 rbenv exec rails _3.0.11_ new my_project
STEP 3. Don't forget to go into that project and set the local rbenv ruby version.
% cd my_project
% rbenv local 1.9.2-p290
Now if you want to delete this project, just delete it as normal.
If you want to delete / manage a rails version from rbenv gems, you can use regular gem commands, just prefix your command line with:
% RBENV_VERSION=1.9.2-p290 rbenv exec gem {some command}
And of course, you can delete a complete ruby version and all its shims, etc that are managed within rbenv pretty easily. I like how self contained everything is.
Hope this helps.
For reference, this is a pretty good walk through of at least some of this stuff:
http://ascarter.net/2011/09/25/modern-ruby-development.html
There is a rbenv plugin called rbenv-gemset which should behave similar to the rvm gemset-command but since rbenv was never intended to work this way, I haven't tried it.
I usually manage Rails versions with Bundler as Nathan suggested in the comments of one of the other answers. I create a Gemfile with my desired Rails version, run bundle install, create the Rails application, let it replace the Gemfile and let Bundler take over:
mkdir my-rails-app
cd my-rails-app
echo "source 'https://rubygems.org'" > Gemfile
echo "gem 'rails', '3.2.17'" >> Gemfile
bundle install
bundle exec rails new . --force --skip-bundle
bundle update
If you want more detail, I wrote an article on my blog about it.
Hope it helps!
If you have setup ruby using rbenv the following will work.
Installing rails, the latest version (7.x as of Oct 2022)
gem install rails -v 7.0.2.4
# Find exe
rbenv rehash
To create a rails project with the latest rails version,
rails new project_1
This will create a rails application with the latest version, to verify we can see the rails version in the Gemspec file (or) see the logs during the installation,
Installing rails, 6.x.x.x version
Assuming we are going to install rails 6.0.4.8, then issue the following commands
gem install rails -v 6.0.4.8
rbenv rehash
Now, to create a rails project with 6.0.4.8 version (which is installed previously), specify the rails version along with the rails command.
rails _6.0.4.8_ new project_2
This will create a rails application with the 6.x version, to verify we can see the rails version in the Gemspec file (or) see the logs during the installation,
Other notes
Similarly, we can manage any no of rails versions in any number of
projects.
rbenv rehash Installs shims for all Ruby executables known to
rbenv
In this approach, you don't need to set or modify any ruby
environment variables.
You don't need to modify Gemspec file by yourself.
The instructions work as of Oct 2022.

Resources