[Ruby] The reason why I haven’t run gem install rails command [never] for 10 years in Ruby

6 minute read

The title is fishing.

The subject is too big and I am a little nervous. Let’s talk about the title.

Conclusion

  • In conclusion, because the environment of Ruby is dirty
  • The gem install xxx command is basically installed in the Ruby environment.
    • So Ruby will have state and lack idempotency
  • Given that there is a convenient mechanism called bundler, I think that the situations that execute gem install xxx will be limited.
  • Be aware of what is happening when you use the gem install, bundle install commands

Development environment construction dilemma

There are various ways to build a development environment.

The fact that there is no uniform method is both a merit and a demerit. (In the sense of freedom)

However, “I’m not sure, but it’s on Qiita, and it worked, so I don’t mind that procedure” is a problem.

The software published on OSS is published in a form that is specific to the application. I would like to show you how to make good use of it.

Concrete example

For example, there is an article like this

(Ubuntu)Ruby on rails 6.0 environment construction

It’s worth noting that this article isn’t bad, it’s just that I don’t follow these steps.

Then how do you do it?

I follow these steps when building a Rails project: First of all, I will outline it and then write specific commands

  1. Install the packages (libraries, etc.) required to build Ruby in advance
  2. Install Ruby using rbenv
  3. Install Node.js required for Rails 6 or later
  4. Create a directory for your project with an appropriate name (example_project)
  5. Execute the bundle init command under the project directory to create a Gemfile file
  6. Edit the created Gemfile file and enable (comment in) the line that says gem'rails'.
  7. Run bundle install --path=vendor/bundle to install the gem under a specific path
  8. Start with the rails s command

Now, let’s write a concrete command. The environment assumes Ubuntu Linux.

Start with no Ruby. Almost almost the same as “(Ubuntu)Ruby on rails 6.0 environment construction”, but the order is different.

Preparation

# Update apt package information
sudo apt update -y
# Update software installed on Ubuntu
sudo apt upgrade -y
# Install packages required for building Ruby via apt
sudo apt install build-essential -y
sudo apt install -y libssl-dev libreadline-dev zlib1g-dev

# To use sqlite3, install the library related to sqlite3
sudo apt install libsqlite3-dev

# For PostgreSQL, execute the following command
sudo apt-get install postgresql-common
sudo apt-get install libpq-dev

# In case of MySQL or MariaDB, execute the following command
sudo apt-get install libmysqlclient-dev

Install Ruby

# rbenv (package management tool) installed
git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
# Set Path to environment variable
echo'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
echo'eval "$(rbenv init -)"' >> ~/.bashrc
# Restart shell
exec $SHELL -l

# install ruby-build
git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build

# Install Ruby
rbenv install 2.6.2
rbenv global 2.6.2

install # bundler command as gem
# From Ruby 2.6, bundler is included, so the following steps are unnecessary. Required before 2.5
gem install bundler

Up to this point, Ubuntu Linux has ruby command, gem command, and bundler command installed.

It still takes a while to start developing with Ruby on Rails.

However, in this state, it is complete until you start writing a Ruby program.

The procedure is different from here

Next, install Node.js that Rails 6 or later requires.

# node.js, install npm
sudo apt install -y nodejs npm
# n package install
sudo npm install n -g
install node using #n package
sudo n stable
# Delete old node.js, npm that I put in first
sudo apt purge -y nodejs npm
# Re-login
exec $SHELL -l
# install yarn package
sudo npm install yarn -g
Check if the version of #node.js is the latest version
node -v

After this step, ruby (2.6.2) and gem command, node, and yarn command are installed on Ubuntu Linux.

Let’s take a break here.

With these preparations, you are ready to run Rails 6!

Next, create the project directory you want to create and set up Rails.

# Create a directory for your project
mkdir example_project
# Move to the created directory
cd example_project

Run # bundle init to create a Gemfile file
bundle init

# Edit the created Gemfile and comment in the "# gem'rails'" part
# Delete the # (sharp) in the part that says "# gem "rails"" to form "gem'rails'"
gedit Gemfile

# bundle install to install rails
bundle install --path vendor/bundle

Execute the #rails new command to install rails gems together
bundle exec rails new ..
(Here, the English message "Do you want to overwrite?" is displayed. Enter "Y".)

With these steps, Rails is ready to use.

bundle exec rails s

** 2020/07/18 Update **

Please point it out in the comments and mention about --path vendor/bundle when doing a bundle install. Since Bundler 2.1, the --path option is deprecated (deprecated). Please refer to here for the handling regarding this point.

Response procedure when the warning “[DEPRECATED] The –path flag is deprecated” occurs during bundle install

Commentary

I will explain what kind of state it is like

First, the figure shows the state in which the library, which is “preparation”, is inserted.

Screenshots 2020-07-17 22.48.57.png

These are the libraries installed on Linux. This alone does not allow you to execute Ruby commands (though it is natural because Ruby is not installed).

In the “Install Ruby” status, the status is as follows:

 Screenshot 2020-07-17 23.01.28.png

The ruby and gem commands are installed based on the library of “Packages installed on Ubuntu Linux”. The reason there is a bundler command is that the gem install bundler command is used to install the bundle command.

The following shows the state where “Node.js” is installed.

Screenshots 2020-07-17 23.24.08.png

The dotted line shows that it has been deleted with the sudo apt purge -y nodejs npm command.

In this state, ruby, gem, bundler, node, npm, yarn commands can be executed.The point to be aware of is that for Ruby, only the ruby, gem, and bundler commands can be executed, and in JavaScript, the node, npm, and yarn commands can be executed. only.

Next, the state of “creating the directory of the project you want to create and setting up Rails” is shown.

![Screenshot 2020-07-17 23.36.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19717/adece39e-e988-64e9-13bd-(06b80acc2c38.png)

Yes, this means that the vendor/bundle has the libraries needed for your project installed.

Since it is difficult to understand the contrast if it is only this, I show the case where gem install rails is executed.

![Screenshot 2020-07-17 23.39.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19717/135f440a-d64f-c908-f037-(d114f8744020.png)

It is shown in red because I want to emphasize it.

What I would like to say here is that the gem of rails that executes the **`rails` command and the version of "rails related gems are stored under the vendor/bundle directory" may be different. There is **.

Such a state cannot be completely reproduced unless the gem of the specific version installed in ruby and the version of the gem installed under vendor/bundle do not match (idempotency (should It means that there is no situation))”.

On the other hand, the above-mentioned method (method without using gem install rails) does not depend on “programs installed under HOME directory of Ubuntu Linux”.

Therefore, by effectively using the bundler command to install the libraries required for the program under a specific directory, and saying “Keep the Ruby standard gem environment as simple as possible” I think you can live a Ruby life.

(Although this story is probably the same for an ecosystem that has a package management system such as Python.)

Therefore, I think it is important to properly execute ** by understanding what each command is responsible for and what it is suitable for.

Since I am writing at a momentum, please forgive my random writing.

#

  • Why do I have to install Node.js to build a Ruby on Rails environment! Story
    • Rails 6 has made webpacker the standard
    • webpacker must use yarn, the ecosystem of node.js
    • There is a subtle feeling that it is not completed in one language, but rather than having to worry about JS related things, it means that it will be happier in the long term to get on the Node.js ecosystem. I personally interpret that.