20200305のRubyに関する記事は15件です。

もう悩まない!MacでRails環境構築する手順の全て

この記事は

初心者でも迷わず環境構築ができるよう、1つ1つの手順を丁寧に解説した記事です。
コマンドが羅列された記事はよく見かけますが、結局コマンドの意味がわからず理解が深まらないことが多々あったので、なるべくコマンドの解説もつけるようにしました。

「環境構築が苦手、よくわからない」という方は、ぜひ参考にしていただければと思います。
また「railsのバージョン指定がうまくいかない...」と悩んでいる方にも参考になると思います。

マシンスペック

参考までに、私のマシンスペックは以下の通りです。

  • macOS Catalina 10.15.3
  • MacBook Air (Retina, 13-inch, 2018)
  • Intel Core i5
  • メモリ 8GB

Ruby, Railsのバージョン

それぞれ下記バージョンで構築することを目指します。

  • Ruby 2.5.7
  • Rails 5.2.3

全体の流れ

この順番でインストールしていきます。

  1. rbenv(Rubyのバージョン管理ツール)
  2. Ruby
  3. PostgreSQL(データベース)
  4. Rails

構築手順

1. rbenvのインストール

rbenvとは、Rubyのバージョンを簡単に切り替えてくれるツールです。

1台のPCで複数のRailsアプリを作ろうとしたとき、「こっちのアプリではRuby2.5.0を使いたいけど、こっちはRuby2.6.0を使いたい...」という欲求が出てきたりします。
そんなときに活躍するのがrbenvです。
詳しい使い方は後で見ていくとして、まずはインストールしてしまいましょう。

rbenvをインストールするためにはHomebrewが必要で、HomebrewをインストールするためにはCommand Line Toolsが必要です。
順番に進めていきます。

1-1. Command Line Toolsのインストール

ターミナルを開き、次のコマンドを実行します。

# Command Line Toolsのインストール
$ xcode-select --install

Xcodeというツールをインストールしていない場合は「インストールしますか?」という画面が表示されるため、「インストール」を選択します。
Xcodeは重いので、少し時間がかかるかもしれません。

インストール完了後、次のコマンドでバージョンが表示されたら成功です。

# バージョン確認
$ xcodebuild -version

1-2. Homebrewのインストール

続いてHomebrewをインストールします。
Homebrewの公式サイトに飛ぶとインストール用のコマンドが用意されてるので、それをターミナルに貼り付けて実行するだけです。
コマンドは随時アップデートされたりするので、直接サイトから持ってくるのが賢明です。

ちなみにHomebrewとは、Macにデフォルトで入っていないソフトをインストールするためのツールです。
上の画像を見ると、「Appleが用意していないあなたの必要なものをインストールします」と書いてありますが、噛み砕くとそういうことです。
Homebrewを入れておくといろいろインストールできて便利なんだな、と理解しておけば大丈夫です。

1-3. rbenvのインストール

いよいよrbenvのインストールを行います。
ターミナルで次の3つのコマンドを順番に実行してください。

# (1) rbenvを初期化する処理を設定
$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile

# (2) 初期化設定の反映
$ source ~/.bash_profile

# (3) rbenvのインストール
$ brew install rbenv ruby-build

(3)では、rbenvと一緒に、rbenvのプラグインであるruby-buildもインストールしています。
rbenvについて詳しく知りたい方は、こちらのブログで詳しく紹介されていますので読んでみてください(ただ、初学者には難易度高めです)。

このrbenvを使って、Rubyをインストールしていきます!

2. Rubyのインストールとバージョン適用

2-1. Rubyのインストール

rbenvでインストールできるバージョンは下記コマンドで確認できます。

# rbenvでインストールできるバージョンを確認
$ rbenv install --list
#=> Available versions:
#   1.8.5-p52
#   1.8.5-p113
#   ...
#   truffleruby-19.2.0
#   truffleruby-19.2.0.1

今回は2.5.7をインストールします。

# Ruby2.5.7をインストール
$ rbenv install 2.5.7

これでRuby2.5.7がインストールされたはずです。
次のコマンドを打ってみましょう。

# インストール済みのRubyのバージョン一覧を表示する
$ rbenv versions
#=> * system (set by /Users/<ユーザ名>/.rbenv/version)
#     2.5.7

これは、system(Macのデフォルト)と2.5.7の2種類のRubyバージョンがPCにインストール済みであることを示しています。
2.5.7もインストールできたことがわかりますね。
ちなみに「*」がついている方が、現在の環境に適用されているバージョンです。

2-2. 作業ディレクトリの作成&移動

続けて作業ディレクトリ(フォルダ)を作成します。
作業ディレクトリの名前は「sample_app」や「workspace」などがよくありますが、作成するアプリ名にするとわかりやすいでしょう。
ここでは私が作成したアプリ名「cooklog」とします。

作業ディレクトを作成します。

# 作業ディレクトリを作成
$ mkdir ~/cooklog

ここまでは「ターミナルにおいてどのフォルダでコマンドを打つか」は気にしなくてよかったですが、ここからは作業フォルダに入ってコマンドを打っていくことになります。
そこで、ディレクトリへの移動を行います。

# 作業ディレクトリへ移動(適宜パスを指定)
$ cd cooklog

2-3. Rubyのバージョンを適用

それでは作業ディレクトリに対してRuby2.5.7を適用します。
先ほど作ったディレクトリにいることを確認して、次のコマンドを実行します。

# 現在のディレクトリにRuby2.5.7を適用
$ rbenv local 2.5.7

# 適用を反映
$ rbenv rehash

これで作業ディレクトリに適用するRubyのバージョンが変わったはずです。確認してみましょう。

$ ruby -v
#=> ruby 2.5.7p206 (2019-10-01 revision 67816) [x86_64-darwin19]

$ rbenv versions
#=>   system (set by /Users/<ユーザ名>/.rbenv/version)
#   * 2.5.7

Rubyのバージョンは、p206..以降が違っても問題ありません。
「*」2.5.7の方に移り、適用バージョンが変わったことを確認できました。

※ちなみにrbenv local x.x.xが現在のディレクトリのRubyバージョンを変更するのに対し、rbenv global x.x.xは使っているPCでデフォルトで使うRubyバージョンを指定します。
したがって、globalの方を使ってもOKです(今回は他のディレクトリへ影響することを避けるため、localにしています)。

2-4. bundlerのインストール

2章の最後に、gemのインストールには欠かせないbundlerをインストールしておきます。
次のコマンドを実行してください。

$ gem install bundler

3. PostgreSQLのインストール

続いてデータベースのインストールを行います。
今回はPostgreSQLを使うことにします。

次のコマンドを打ち込んで、インストールと起動を一気にやってしまいましょう。

# PostgreSQLのインストール
$ brew install postgresql

# PostgreSQLの起動
$ brew services start postgresql
==> Successfully started `postgresql` (label: homebrew.mxcl.postgresql)

4. Railsのインストール

ここからいよいよRailsをインストールしていきます。

まずはバージョンは気にせず、Railsをインストールします。

$ gem install rails

続けて、作成するアプリのバージョンは5.2.3とするので、次のコマンドを打ち込んでください。

# Railsアプリ作成(gemのインストールはスキップ)
$ rails _5.2.3_ new . --skip-bundle

途中、何か聞かれたら全てy(yesの意味)を打ってEnterを押せばOKです。
.はカレント(現在の)ディレクトリという意味です。

--skip-bundleの部分がポイントで、これをつけるとgemのインストールは後回しにしてRailsアプリに必要なファイルだけを先に作ってくれます。

次に作られたファイルの中のGemfileを開き、次のように書き換えます。

Gemfile
# 変更前
gem 'rails', '~> 5.2.3'
# 変更後
gem 'rails', '= 5.2.3'

'~> 5.2.3'は「バージョン5.2.3以上のものをインストールします」という意味なので、確実に5.2.3をインストールするためにこの変更を行います。

そして、次のコマンドを実行して各種gemをインストールします。

# 各種gemをインストール
$ bundle install

Railsのバージョンを確認し、きちんとインストールできていることを確認しましょう。

$ rails -v
#=> 5.2.3

最後に、Railsアプリを立ち上げるためにRailsサーバーを起動します。

$ rails s
=> Booting Puma
=> Rails 5.2.3 application starting in development 
...(省略)...
* Listening on tcp://localhost:3000
Use Ctrl-C to stop

上の感じになったらOKです。
http://localhost:3000/にアクセスしてみましょう。

スクリーンショット 2020-03-05 22.32.22.png

この画面が表示されれば、きちんとRailsアプリが立ち上がっています!
Rails 5.2.3Ruby 2.5.7が適用されていることがわかりますね。

これにて環境構築はおしまいです。

お疲れ様でした!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【完全版】MacでRails環境構築する手順の全て

この記事は

初心者でも迷わず環境構築ができるよう、1つ1つの手順を丁寧に解説した記事です。
なるべく「どうしてこのコマンドを実行するのか」も解説するようにしています。

「環境構築が苦手、よくわからない」という方は、ぜひ参考にしていただければと思います。
また「railsのバージョン指定がうまくいかない...」と悩んでいる方にも参考になると思います。

※もしこれを読んでもうまくいかなければ、ぜひ積極的にコメントいただけますと幸いです!

マシンスペック

参考までに、私のマシンスペックは以下の通りです。

  • macOS Catalina 10.15.3
  • MacBook Air (Retina, 13-inch, 2018)
  • Intel Core i5
  • メモリ 8GB

Ruby, Railsのバージョン

それぞれ下記バージョンで構築することを目指します。

  • Ruby 2.5.7
  • Rails 5.2.3

全体の流れ

この順番でインストールしていきます。

  1. rbenv(Rubyのバージョン管理ツール)
  2. Ruby
  3. PostgreSQL(データベース)
  4. Rails

構築手順

1. rbenvのインストール

rbenvとは、Rubyのバージョンを簡単に切り替えてくれるツールです。

1台のPCで複数のRailsアプリを作ろうとしたとき、「こっちのアプリではRuby2.5.0を使いたいけど、こっちはRuby2.6.0を使いたい...」という欲求が出てきたりします。
そんなときに活躍するのがrbenvです。
詳しい使い方は後で見ていくとして、まずはインストールしてしまいましょう。

rbenvをインストールするためにはHomebrewが必要で、HomebrewをインストールするためにはCommand Line Toolsが必要です。
順番に進めていきます。

1-1. Command Line Toolsのインストール

ターミナルを開き、次のコマンドを実行します。

# Command Line Toolsのインストール
$ xcode-select --install

Xcodeというツールをインストールしていない場合は「インストールしますか?」という画面が表示されるため、「インストール」を選択します。
Xcodeは重いので、少し時間がかかるかもしれません。

インストール完了後、次のコマンドでバージョンが表示されたら成功です。

# バージョン確認
$ xcodebuild -version

1-2. Homebrewのインストール

続いてHomebrewをインストールします。
Homebrewの公式サイトに飛ぶとインストール用のコマンドが用意されてるので、それをターミナルに貼り付けて実行するだけです。
コマンドは随時アップデートされたりするので、直接サイトから持ってくるのが賢明です。

ちなみにHomebrewとは、Macにデフォルトで入っていないソフトをインストールするためのツールです。
上の画像を見ると、「Appleが用意していないあなたの必要なものをインストールします」と書いてありますが、噛み砕くとそういうことです。
Homebrewを入れておくといろいろインストールできて便利なんだな、と理解しておけば大丈夫です。

1-3. rbenvのインストール

いよいよrbenvのインストールを行います。
ターミナルで次の4つのコマンドを順番に実行してください。

# (1) rbenvへのPATHを通す
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc

# (2) rbenvを使うために必要な「rbenv init -」コマンドを設定
$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile

# (3) 設定の反映
$ source ~/.bash_profile

# (4) rbenvのインストール
$ brew install rbenv ruby-build

(4)では、rbenvと一緒に、rbenvのプラグインであるruby-buildもインストールしています。
rbenvについて詳しく知りたい方は、こちらのブログで詳しく紹介されていますので読んでみてください(ただ、初学者には難易度高めです)。

このrbenvを使って、Rubyをインストールしていきます!

2. Rubyのインストールとバージョン適用

2-1. Rubyのインストール

rbenvでインストールできるバージョンは下記コマンドで確認できます。

# rbenvでインストールできるバージョンを確認
$ rbenv install --list
#=> Available versions:
#   1.8.5-p52
#   1.8.5-p113
#   ...
#   truffleruby-19.2.0
#   truffleruby-19.2.0.1

今回は2.5.7をインストールします。

# Ruby2.5.7をインストール
$ rbenv install 2.5.7

これでRuby2.5.7がインストールされたはずです。
次のコマンドを打ってみましょう。

# インストール済みのRubyのバージョン一覧を表示する
$ rbenv versions
#=> * system (set by /Users/<ユーザ名>/.rbenv/version)
#     2.5.7

これは、system(Macのデフォルト)と2.5.7の2種類のRubyバージョンがPCにインストール済みであることを示しています。
2.5.7もインストールできたことがわかりますね。
ちなみに「*」がついている方が、現在の環境に適用されているバージョンです。

2-2. 作業ディレクトリの作成&移動

続けて作業ディレクトリ(フォルダ)を作成します。
作業ディレクトリの名前は「sample_app」や「workspace」などがよくありますが、作成するアプリ名にするとわかりやすいでしょう。
ここでは私が作成したアプリ名「cooklog」とします。

作業ディレクトを作成します。

# 作業ディレクトリを作成
$ mkdir ~/cooklog

ここまでは「ターミナルにおいてどのフォルダでコマンドを打つか」は気にしなくてよかったですが、ここからは作業フォルダに入ってコマンドを打っていくことになります。
そこで、ディレクトリへの移動を行います。

# 作業ディレクトリへ移動(適宜パスを指定)
$ cd cooklog

2-3. Rubyのバージョンを適用

それでは作業ディレクトリに対してRuby2.5.7を適用します。
先ほど作ったディレクトリにいることを確認して、次のコマンドを実行します。

# 現在のディレクトリにRuby2.5.7を適用
$ rbenv local 2.5.7

# 適用を反映
$ rbenv rehash

これで作業ディレクトリに適用するRubyのバージョンが変わったはずです。確認してみましょう。

$ ruby -v
#=> ruby 2.5.7p206 (2019-10-01 revision 67816) [x86_64-darwin19]

$ rbenv versions
#=>   system (set by /Users/<ユーザ名>/.rbenv/version)
#   * 2.5.7

Rubyのバージョンは、p206..以降が違っても問題ありません。
「*」2.5.7の方に移り、適用バージョンが変わったことを確認できました。

※ちなみにrbenv local x.x.xが現在のディレクトリのRubyバージョンを変更するのに対し、rbenv global x.x.xは使っているPCでデフォルトで使うRubyバージョンを指定します。
したがって、globalの方を使ってもOKです(今回は他のディレクトリへ影響することを避けるため、localにしています)。

2-4. bundlerのインストール

2章の最後に、gemのインストールには欠かせないbundlerをインストールしておきます。

まずはターミナルでbundler -vを実行して、bundlerがインストールされているか確認してみてください。

$ bundler -v
#=> Bundler version 1.17.2

上のようにbundlerのバージョンが表示されれば問題ありません。
「not found」と出るのであれば、次のコマンドでインストールしてください。

$ gem install bundler

3. PostgreSQLのインストール

続いてデータベースのインストールを行います。
今回はPostgreSQLを使うことにします。

次のコマンドを打ち込んで、インストールと起動を一気にやってしまいましょう。

# PostgreSQLのインストール
$ brew install postgresql

# PostgreSQLの起動
$ brew services start postgresql
==> Successfully started `postgresql` (label: homebrew.mxcl.postgresql)

4. Railsのインストール

ここからいよいよRailsをインストールしていきます。

まずはバージョンは気にせず、RailsをPC内にインストールします。

$ gem install rails

続けて、作成するアプリのバージョンは5.2.3とするので、次のコマンドを打ち込んでください。

# Railsアプリ作成(gemのインストールはスキップ)
$ rails _5.2.3_ new . --skip-bundle

途中、何か聞かれたら全てy(yesの意味)を打ってEnterを押せばOKです。
.はカレント(現在の)ディレクトリという意味です。

--skip-bundleの部分がポイントで、これをつけるとgemのインストールは後回しにしてRailsアプリに必要なファイルだけを先に作ってくれます。

次に作られたファイルの中のGemfileを開き、次のように書き換えます。

Gemfile
# 変更前
gem 'rails', '~> 5.2.3'
# 変更後
gem 'rails', '= 5.2.3'

'~> 5.2.3'は「バージョン5.2.3以上のものをインストールします」という意味なので、確実に5.2.3をインストールするためにこの変更を行います。

そして、次のコマンドを実行して各種gemをインストールします。

# 各種gemをインストール
$ bundle install

Railsのバージョンを確認し、きちんとインストールできていることを確認しましょう。

$ rails -v
#=> 5.2.3

最後に、Railsアプリを立ち上げるためにRailsサーバーを起動します。

$ rails s
=> Booting Puma
=> Rails 5.2.3 application starting in development 
...(省略)...
* Listening on tcp://localhost:3000
Use Ctrl-C to stop

上の感じになったらOKです。
http://localhost:3000/にアクセスしてみましょう。

スクリーンショット 2020-03-05 22.32.22.png

この画面が表示されれば、きちんとRailsアプリが立ち上がっています!
Rails 5.2.3Ruby 2.5.7が適用されていることがわかりますね。

これにて環境構築はおしまいです。

お疲れ様でした!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【これで完璧!】MacでRails環境構築する手順の全て

この記事は

初心者でも迷わず環境構築ができるよう、1つ1つの手順を丁寧に解説した記事です。
コマンドが羅列された記事はよく見かけますが、結局コマンドの意味がわからず理解が深まらないことが多々あったので、なるべくコマンドの解説もつけるようにしました。

「環境構築が苦手、よくわからない」という方は、ぜひ参考にしていただければと思います。

マシンスペック

参考までに、私のマシンスペックは以下の通りです。

  • macOS Catalina 10.15.3
  • MacBook Air (Retina, 13-inch, 2018)
  • Intel Core i5
  • メモリ 8GB

Ruby, Railsのバージョン

それぞれ下記バージョンで構築することを目指します。

  • Ruby 2.5.7
  • Rails 5.2.3

全体の流れ

この順番でインストールしていきます。

  1. rbenv(Rubyのバージョン管理ツール)
  2. Ruby
  3. PostgreSQL(データベース)
  4. Rails

構築手順

1. rbenvのインストール

rbenvとは、Rubyのバージョンを簡単に切り替えてくれるツールです。

1台のPCで複数のRailsアプリを作ろうとしたとき、「こっちのアプリではRuby2.5.0を使いたいけど、こっちはRuby2.6.0を使いたい...」という欲求が出てきたりします。
そんなときに活躍するのがrbenvです。
詳しい使い方は後で見ていくとして、まずはインストールしてしまいましょう。

rbenvをインストールするためにはHomebrewが必要で、HomebrewをインストールするためにはCommand Line Toolsが必要です。
順番に進めていきます。

1-1. Command Line Toolsのインストール

ターミナルを開き、次のコマンドを実行します。

# Command Line Toolsのインストール
$ xcode-select --install

Xcodeというツールをインストールしていない場合は「インストールしますか?」という画面が表示されるため、「インストール」を選択します。
Xcodeは重いので、少し時間がかかるかもしれません。

インストール完了後、次のコマンドでバージョンが表示されたら成功です。

# バージョン確認
$ xcodebuild -version

1-2. Homebrewインストール

続いてHomebrewをインストールします。
Homebrewの公式サイトに飛ぶとインストール用のコマンドが用意されてるので、それをターミナルに貼り付けて実行するだけです。
コマンドは随時アップデートされたりするので、直接サイトから持ってくるのが賢明です。

ちなみにHomebrewとは、Macにデフォルトで入っていないソフトをインストールするためのツールです。
上の画像を見ると、「Appleが用意していないあなたの必要なものをインストールします」と書いてありますが、噛み砕くとそういうことです。
Homebrewを入れておくといろいろインストールできて便利なんだな、と理解しておけば大丈夫です。

1-3. rbenvインストール

いよいよrbenvのインストールを行います。
ターミナルで次の3つのコマンドを順番に実行してください。

# (1) rbenvを初期化する処理を設定
$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile

# (2) 初期化設定の反映
$ source ~/.bash_profile

# (3) rbenvのインストール
$ brew install rbenv ruby-build

(3)では、rbenvと一緒に、rbenvのプラグインであるruby-buildもインストールしています。
rbenvについて詳しく知りたい方は、こちらのブログで詳しく紹介されていますので読んでみてください(ただ、初学者には難易度高めです)。

このrbenvを使って、Rubyをインストールしていきます!

2. Rubyのインストールとバージョン適用

2-1. Rubyのインストール

rbenvでインストールできるバージョンは下記コマンドで確認できます。

# rbenvでインストールできるバージョンを確認
$ rbenv install --list
#=> Available versions:
#   1.8.5-p52
#   1.8.5-p113
#   ...
#   truffleruby-19.2.0
#   truffleruby-19.2.0.1

今回は2.5.7をインストールします。

# Ruby2.5.7をインストール
$ rbenv install 2.5.7

これでRuby2.5.7がインストールされたはずです。
次のコマンドを打ってみましょう。

# インストール済みのRubyのバージョン一覧を表示する
$ rbenv versions
#=> * system (set by /Users/<ユーザ名>/.rbenv/version)
#     2.5.7

これは、system(Macのデフォルト)と2.5.7の2種類のRubyバージョンがPCにインストール済みであることを示しています。
2.5.7もインストールできたことがわかりますね。
ちなみに「*」がついている方が、現在の環境に適用されているバージョンです。

2-2. 作業ディレクトリの作成&移動

続けて作業ディレクトリ(フォルダ)を作成します。
作業ディレクトリの名前は「sample_app」や「workspace」などがよくありますが、作成するアプリ名にするとわかりやすいでしょう。
ここでは私が作成したアプリ名「cooklog」とします。

作業ディレクトを作成します。

# 作業ディレクトリを作成
$ mkdir ~/cooklog

ここまでは「ターミナルにおいてどのフォルダでコマンドを打つか」は気にしなくてよかったですが、ここからは作業フォルダに入ってコマンドを打っていくことになります。
そこで、ディレクトリへの移動を行います。

# 作業ディレクトリへ移動(適宜パスを指定)
$ cd cooklog

2-3. Rubyのバージョンを適用

それでは作業ディレクトリに対してRuby2.5.7を適用します。
先ほど作ったディレクトリにいることを確認して、次のコマンドを実行します。

# 現在のディレクトリにRuby2.5.7を適用
$ rbenv local 2.5.7

# 適用を反映
$ rbenv rehash

これで作業ディレクトリに適用するRubyのバージョンが変わったはずです。確認してみましょう。

$ ruby -v
#=> ruby 2.5.7p206 (2019-10-01 revision 67816) [x86_64-darwin19]

$ rbenv versions
#=>   system (set by /Users/<ユーザ名>/.rbenv/version)
#   * 2.5.7

Rubyのバージョンは、p206..以降が違っても問題ありません。
「*」2.5.7の方に移り、適用バージョンが変わったことを確認できました。

※ちなみにrbenv local x.x.xが現在のディレクトリのRubyバージョンを変更するのに対し、rbenv global x.x.xは使っているPCでデフォルトで使うRubyバージョンを指定します。
したがって、globalの方を使ってもOKです(今回は他のディレクトリへ影響することを避けるため、localにしています)。

2-4. bundlerのインストール

2章の最後に、gemのインストールには欠かせないbundlerをインストールしておきます。
次のコマンドを実行してください。

$ gem install bundler

3. PostgreSQLのインストール

続いてデータベースのインストールを行います。
今回はPostgreSQLを使うことにします。

次のコマンドを打ち込んで、インストールと起動を一気にやってしまいましょう。

# PostgreSQLのインストール
$ brew install postgresql

# PostgreSQLの起動
$ brew services start postgresql
==> Successfully started `postgresql` (label: homebrew.mxcl.postgresql)

4. Railsのインストール

ここからいよいよRailsをインストールしていきます。

バージョンは5.2.3とするので、次のコマンドを打ち込んでください。

# Railsアプリ作成(gemのインストールはスキップ)
$ rails _5.2.3_ new . --skip-bundle

途中、何か聞かれたら全てy(yesの意味)を打ってEnterを押せばOKです。
.はカレント(現在の)ディレクトリという意味です。

--skip-bundleの部分がポイントで、これをつけるとgemのインストールは後回しにしてRailsアプリに必要なファイルだけを先に作ってくれます。

次に作られたファイルの中のGemfileを開き、次のように書き換えます。

Gemfile
# 変更前
gem 'rails', '~> 5.2.3'
# 変更後
gem 'rails', '= 5.2.3'

'~> 5.2.3'は「バージョン5.2.3以上のものをインストールします」という意味なので、確実に5.2.3をインストールするためにこの変更を行います。

そして、次のコマンドを実行して各種gemをインストールします。

# 各種gemをインストール
$ bundle install

Railsのバージョンを確認し、きちんとインストールできていることを確認しましょう。

$ rails -v
#=> 5.2.3

最後に、Railsアプリを立ち上げるためにRailsサーバーを起動します。

$ rails s
=> Booting Puma
=> Rails 5.2.3 application starting in development 
...(省略)...
* Listening on tcp://localhost:3000
Use Ctrl-C to stop

上の感じになったらOKです。
http://localhost:3000/にアクセスしてみましょう。

スクリーンショット 2020-03-05 22.32.22.png

この画面が表示されれば、きちんとRailsアプリが立ち上がっています!
Rails 5.2.3Ruby 2.5.7が適用されていることがわかりますね。

これにて環境構築はおしまいです。

お疲れ様でした!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【これで完璧!】MacでRails環境構築する手順を超丁寧に解説する

この記事は

初心者でも迷わず環境構築ができるよう、1つ1つの手順を丁寧に解説した記事です。
コマンドが羅列された記事はよく見かけますが、結局コマンドの意味がわからず理解が深まらないことが多々あったので、なるべくコマンドの解説もつけるようにしました。

「環境構築が苦手、よくわからない」という方は、ぜひ参考にしていただければと思います。
また「railsのバージョン指定がうまくいかない...」と悩んでいる方にも参考になると思います。

マシンスペック

参考までに、私のマシンスペックは以下の通りです。

  • macOS Catalina 10.15.3
  • MacBook Air (Retina, 13-inch, 2018)
  • Intel Core i5
  • メモリ 8GB

Ruby, Railsのバージョン

それぞれ下記バージョンで構築することを目指します。

  • Ruby 2.5.7
  • Rails 5.2.3

全体の流れ

この順番でインストールしていきます。

  1. rbenv(Rubyのバージョン管理ツール)
  2. Ruby
  3. PostgreSQL(データベース)
  4. Rails

構築手順

1. rbenvのインストール

rbenvとは、Rubyのバージョンを簡単に切り替えてくれるツールです。

1台のPCで複数のRailsアプリを作ろうとしたとき、「こっちのアプリではRuby2.5.0を使いたいけど、こっちはRuby2.6.0を使いたい...」という欲求が出てきたりします。
そんなときに活躍するのがrbenvです。
詳しい使い方は後で見ていくとして、まずはインストールしてしまいましょう。

rbenvをインストールするためにはHomebrewが必要で、HomebrewをインストールするためにはCommand Line Toolsが必要です。
順番に進めていきます。

1-1. Command Line Toolsのインストール

ターミナルを開き、次のコマンドを実行します。

# Command Line Toolsのインストール
$ xcode-select --install

Xcodeというツールをインストールしていない場合は「インストールしますか?」という画面が表示されるため、「インストール」を選択します。
Xcodeは重いので、少し時間がかかるかもしれません。

インストール完了後、次のコマンドでバージョンが表示されたら成功です。

# バージョン確認
$ xcodebuild -version

1-2. Homebrewのインストール

続いてHomebrewをインストールします。
Homebrewの公式サイトに飛ぶとインストール用のコマンドが用意されてるので、それをターミナルに貼り付けて実行するだけです。
コマンドは随時アップデートされたりするので、直接サイトから持ってくるのが賢明です。

ちなみにHomebrewとは、Macにデフォルトで入っていないソフトをインストールするためのツールです。
上の画像を見ると、「Appleが用意していないあなたの必要なものをインストールします」と書いてありますが、噛み砕くとそういうことです。
Homebrewを入れておくといろいろインストールできて便利なんだな、と理解しておけば大丈夫です。

1-3. rbenvのインストール

いよいよrbenvのインストールを行います。
ターミナルで次の3つのコマンドを順番に実行してください。

# (1) rbenvを初期化する処理を設定
$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile

# (2) 初期化設定の反映
$ source ~/.bash_profile

# (3) rbenvのインストール
$ brew install rbenv ruby-build

(3)では、rbenvと一緒に、rbenvのプラグインであるruby-buildもインストールしています。
rbenvについて詳しく知りたい方は、こちらのブログで詳しく紹介されていますので読んでみてください(ただ、初学者には難易度高めです)。

このrbenvを使って、Rubyをインストールしていきます!

2. Rubyのインストールとバージョン適用

2-1. Rubyのインストール

rbenvでインストールできるバージョンは下記コマンドで確認できます。

# rbenvでインストールできるバージョンを確認
$ rbenv install --list
#=> Available versions:
#   1.8.5-p52
#   1.8.5-p113
#   ...
#   truffleruby-19.2.0
#   truffleruby-19.2.0.1

今回は2.5.7をインストールします。

# Ruby2.5.7をインストール
$ rbenv install 2.5.7

これでRuby2.5.7がインストールされたはずです。
次のコマンドを打ってみましょう。

# インストール済みのRubyのバージョン一覧を表示する
$ rbenv versions
#=> * system (set by /Users/<ユーザ名>/.rbenv/version)
#     2.5.7

これは、system(Macのデフォルト)と2.5.7の2種類のRubyバージョンがPCにインストール済みであることを示しています。
2.5.7もインストールできたことがわかりますね。
ちなみに「*」がついている方が、現在の環境に適用されているバージョンです。

2-2. 作業ディレクトリの作成&移動

続けて作業ディレクトリ(フォルダ)を作成します。
作業ディレクトリの名前は「sample_app」や「workspace」などがよくありますが、作成するアプリ名にするとわかりやすいでしょう。
ここでは私が作成したアプリ名「cooklog」とします。

作業ディレクトを作成します。

# 作業ディレクトリを作成
$ mkdir ~/cooklog

ここまでは「ターミナルにおいてどのフォルダでコマンドを打つか」は気にしなくてよかったですが、ここからは作業フォルダに入ってコマンドを打っていくことになります。
そこで、ディレクトリへの移動を行います。

# 作業ディレクトリへ移動(適宜パスを指定)
$ cd cooklog

2-3. Rubyのバージョンを適用

それでは作業ディレクトリに対してRuby2.5.7を適用します。
先ほど作ったディレクトリにいることを確認して、次のコマンドを実行します。

# 現在のディレクトリにRuby2.5.7を適用
$ rbenv local 2.5.7

# 適用を反映
$ rbenv rehash

これで作業ディレクトリに適用するRubyのバージョンが変わったはずです。確認してみましょう。

$ ruby -v
#=> ruby 2.5.7p206 (2019-10-01 revision 67816) [x86_64-darwin19]

$ rbenv versions
#=>   system (set by /Users/<ユーザ名>/.rbenv/version)
#   * 2.5.7

Rubyのバージョンは、p206..以降が違っても問題ありません。
「*」2.5.7の方に移り、適用バージョンが変わったことを確認できました。

※ちなみにrbenv local x.x.xが現在のディレクトリのRubyバージョンを変更するのに対し、rbenv global x.x.xは使っているPCでデフォルトで使うRubyバージョンを指定します。
したがって、globalの方を使ってもOKです(今回は他のディレクトリへ影響することを避けるため、localにしています)。

2-4. bundlerのインストール

2章の最後に、gemのインストールには欠かせないbundlerをインストールしておきます。
次のコマンドを実行してください。

$ gem install bundler

3. PostgreSQLのインストール

続いてデータベースのインストールを行います。
今回はPostgreSQLを使うことにします。

次のコマンドを打ち込んで、インストールと起動を一気にやってしまいましょう。

# PostgreSQLのインストール
$ brew install postgresql

# PostgreSQLの起動
$ brew services start postgresql
==> Successfully started `postgresql` (label: homebrew.mxcl.postgresql)

4. Railsのインストール

ここからいよいよRailsをインストールしていきます。

まずはバージョンは気にせず、Railsをインストールします。

$ gem install rails

続けて、作成するアプリのバージョンは5.2.3とするので、次のコマンドを打ち込んでください。

# Railsアプリ作成(gemのインストールはスキップ)
$ rails _5.2.3_ new . --skip-bundle

途中、何か聞かれたら全てy(yesの意味)を打ってEnterを押せばOKです。
.はカレント(現在の)ディレクトリという意味です。

--skip-bundleの部分がポイントで、これをつけるとgemのインストールは後回しにしてRailsアプリに必要なファイルだけを先に作ってくれます。

次に作られたファイルの中のGemfileを開き、次のように書き換えます。

Gemfile
# 変更前
gem 'rails', '~> 5.2.3'
# 変更後
gem 'rails', '= 5.2.3'

'~> 5.2.3'は「バージョン5.2.3以上のものをインストールします」という意味なので、確実に5.2.3をインストールするためにこの変更を行います。

そして、次のコマンドを実行して各種gemをインストールします。

# 各種gemをインストール
$ bundle install

Railsのバージョンを確認し、きちんとインストールできていることを確認しましょう。

$ rails -v
#=> 5.2.3

最後に、Railsアプリを立ち上げるためにRailsサーバーを起動します。

$ rails s
=> Booting Puma
=> Rails 5.2.3 application starting in development 
...(省略)...
* Listening on tcp://localhost:3000
Use Ctrl-C to stop

上の感じになったらOKです。
http://localhost:3000/にアクセスしてみましょう。

スクリーンショット 2020-03-05 22.32.22.png

この画面が表示されれば、きちんとRailsアプリが立ち上がっています!
Rails 5.2.3Ruby 2.5.7が適用されていることがわかりますね。

これにて環境構築はおしまいです。

お疲れ様でした!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

PythonとRubyのインスタントメソッド文法(勉強中)

今回はPythonとRubyの勉強として、
インスタンスメソッドの文法を比較してみたいと思います。
インスタンスメソッドはオブジェクト指向の基本的な内容で、
様々な言語で比較してみたいと考えております。

今回の用いるPythonとRubyは下記バージョンで実施しております。
Python: 3.7.4
Ruby: 2.6.3

Pythonでの例

test.py
class Test:
     def __init__(self):
          print('勉強中')

Rubyでの例

test.rb
class Test
     def initialize
         puts('勉強中')
     end
end

比較のすると「:」や「end」の有無などが違うかなという印象です。

随時更新させていただきます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Ruby 2.7.0 で速度が重要なときは double splat 引数に double splat 演算子をつけてハッシュを渡すより単にハッシュをハッシュとして渡すほうが良い

Ruby 2.7.0 にして、キーワード引数関連の大量の警告を出ないように変更していったところ、指定の時間内で処理が終わるというテストが失敗するようになったため、もしかして警告に合わせて変更した部分が影響しているのではないかと考え、速度を調べてみました。

RUBY_VERSION                    # => "2.7.0"

h = { a: 1, b: 2, c: 3 }

def f1(o = {})
end

def f2(**o)
end

require "active_support/core_ext/benchmark"
def _; "%7.2f ms" % Benchmark.ms { 1000_0000.times { yield } } end
_ { f1(h)   } # => " 857.01 ms"
_ { f2(h)   } # => "1955.95 ms"
_ { f2(**h) } # => "3679.11 ms"

これでわかったこと

  1. ハッシュをハッシュとして渡すのはかなり速い
  2. f2(**o) にハッシュを渡すのはハッシュをハッシュとして渡すより2倍ほど重い (そもそも警告がでる)
  3. f2(**o) にハッシュを ** をつけて渡すのは単にハッシュをハッシュとして渡すより4倍ほど重い

ということです。

いままで func(options = {}) というのがあると、とりあえず新しい感じの方に合わせとけば利点があるんだろうと考えて func(**options) の方に寄せていってましたが、速度がもっとも重要なところでは、逆に func(options = {}) の方に寄せていった方がよさそうです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Rails】Rakeタスクに:environmentがないとNameErrorが出る

エラー

Rakeタスクを実行したときに、NameError: uninitialized constant ClassNameが出る。

send_summary_mail.rake
namespace :send_summary_mail do
  desc '管理者に記事数一覧をメール送信する'
  task :send_mail do
    SummaryMailer.daily.deliver_now
    puts 'メールを送信しました'
  end
end
$ rake send_summary_mail:send_mail
rake aborted!
NameError: uninitialized constant SummaryMailer
/Users/k_end/workspace/application/lib/tasks/send_mail_summary.rake:4:in `block (2 levels) in <top (required)>'
Tasks: TOP => send_summary_mail:send_mail
(See full trace by running task with --trace)

どうやらSummaryMailerが読み込みできていないようです。
しかし、パスは正しいしタイポもしていない……。

試行錯誤

rails cSummaryMailer.daily.deliver_nowを実行する。
→うまくいく。ということは、SummaryMailer自体には問題はなさそう。

send_summary_mail.rake
require Rails.root.join("app/mailers/summary_mailer")

を追加する。
NameError: uninitialized constant ApplicationMailer
根本的にダメそう。

send_summary_mail.rake
namespace :send_summary_mail do
  desc '管理者に記事数一覧をメール送信する'
  task :send_mail do
    # SummaryMailer.daily.deliver_now
    puts 'メールを送信しました'
  end
end

原因であろう部分をコメントアウトしてみる。
→うまくいく。

この辺から、「多分RakeタスクがRails環境で実行されていないんだろうなー」と予測。

原因

taskに:environmentを付けていませんでした。generateした時点で自動的に付いているはずなのですが、どこかで消えていた模様。

namespace :send_summary_mail do
  desc '管理者に記事数一覧をメール送信する'
  task send_mail: :environment do
    SummaryMailer.daily.deliver_now
    puts 'メールを送信しました'
  end
end
$ rake send_summary_mail:send_mail
メールを送信しました

無事、SummatyMailerを呼び出してタスクを実行することができました。
気が付いてみれば大したことがないのに、ハマるときは無駄にハマる。

リンク

:environmentで何やってるの?という点についてまとめている先人がいました。
Rails における rake タスクの :environment について

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【RSpec】toggleされた要素へのクリック対応

はじめに

RSpecでユーザー登録の統合テストをかいているときに、
toggleされた要素に対するクリックのやり方でつまづきました。
僕と同じ初学者の方の参考になりましたら幸いです。

RSpecでのテスト

RSpecでの簡単なテストを一部抜粋。
ルートページで「新規登録」ボタンをおすと、
「ユーザーの新規登録」と記載されているページに遷移することを確認するテスト。

it 'ユーザー登録ページが表示される' do
  visit root_path
  click_on '新規登録'
  expect(page).to have_content 'ユーザーの新規登録'
end

下記エラーが発生。

Failure/Error: click_on '新規登録'

     Capybara::ElementNotFound:
       Unable to find visible link or button "新規登録"

slimには=link_to signup_path, class: 'nav-link' do | 新規登録のコードがあり、
ブラウザでページを表示させても「新規登録」ボタンは確かにあるのに、上記エラーが発生。

Bootstrapのtoggleが原因

テスト用のブラウザでは「新規登録」ボタンがtoggle化されていたため、
エラーが発生していた。

試しに、下記のように内容を変更してみる。

it '新規登録ボタンの確認' do
  visit root_path
  expect(page).to have_content '新規登録'
end
Failure/Error: expect(page).to have_content '新規登録'
       expected to find text "新規登録" in (略).
 (However, it was found 1 time including non-visible text.)

「non-visible text」としては「新規登録」があるとの指摘。

対応

toggleのアイコンをクリックするステップを入れる。

it 'ユーザー登録ページが表示される' do
  visit root_path
 find(".navbar-toggler-icon").click
  click_on '新規登録'
  expect(page).to have_content 'ユーザーの新規登録'
end

これで解決。

 

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Rails】/users/:id ではなく/:username にする

理想

スクリーンショット 2020-03-05 16.54.21.png


やり方

to_paramを使用する

user.rb
class User < ActiveRecord::Base
  validates_presence_of :username
  validates_uniqueness_of :username, case_sensitive: false

  def to_param
    username
  end

users_controller.rb
class UsersController < ApplicationController
  def show
    @user = User.find_by(username: params[:id])
  end
end
routes.rb
  resources: users, path: '/', only: [:show]
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

スクリプト言語 KINX/【雑多なこと】その後サポートした機能

はじめに

見た目は JavaScript頭脳(中身)は Ruby、(安定感は AC/DC)」になっているかはさておき。

解説ばっかりで疲れてきたので、解説とは別に雑多な話題をご提供。いくつか機能をサポートしました。ドキュメントをそろえてバージョン 1 を何とかリリースしたいところ。

その後サポートした機能

構文的な追加とライブラリの追加をしました。

構文

module

modulemixin という予約語で、後から機能をアタッチできる仕組み。

module Printable {
    public print() {
        System.print(@value); // `this` is not Printable's instance but host class's instance.
                              // In this case, this means Value's instance.
    }
    public println() {
        System.println(@value);
    }
}

class Value(v) {
    mixin Printable;
    private initialize() {
        @value = v;
    }
}

var v = new Value(100);
v.println();    // 100

namespace

名前空間。クラスとモジュールは自動的に名前空間に属し、名前空間を経由してアクセス可能。

namespace Name1 {

    class X {
        public methodX() {
            System.println("x1");
        }
    }

    var x = new X();
    x.methodX(); // x1

    namespace Name2 {
        class X {
            public methodX() {
                System.println("x2");
            }
        }

        var x = new X();
        x.methodX(); // x2
    } // namespace Name2

} // namespace Name1

var x1 = new Name1.X();
x1.methodX(); // x1

var x2 = new Name1.Name2.X();
x2.methodX(); // x2

ライブラリ

下記のサンプルはリポジトリ にもコミットしてある。

Zip

Zip による圧縮・解凍をサポート。試してないが、使ったライブラリの説明によれば Zip64 もいける(自動的に対処される)はず。WinZIP の AES アルゴリズムには対応されているのを確認した。ただし、AES 暗号化を有効にしてしまうと Windows の Explorer で解凍できなくなるが強固にはなる。こんな感じ。

import Zip;

var zip = new Zip("examples/zip/ziptest.zip", File.READ|File.WRITE);
zip.setPassword("text");
zip.addFile("README.md", {
    method: "bzip2",
    aes: true,
});
zip.addFile("README.md");
zip.addString("test/test1.txt", {
    content: "test/test\n",
    aes: true,  // Can not use aes option for addString, that means no effect for addString.
});
zip.addString("test/test2.txt", {
    content: "test/test\n",
    password: "text2",
});

System.println("totalFiles = ", zip.totalFiles);
zip.each(function(e) {
    System.println("%s:" % e.filename);
    e.keySet().each(&(key) => {
        if (e[key].isFunction || e[key].isObject || e[key].isUndefined) {
            return;
        }
        if (key == "crc32") {
            System.println("    %-14d = %10X" % key % e[key]);
        } else if (key != "time" && key != "filename") {
            System.println("    %-14d = %10d" % key % e[key]);
        }
    });
    e.time.keySet().each(&(k) => {
        System.println("      time.%-7d = %10d" % k % e.time[k]);
    });
    // if (e.filename == "README.md") {
    //     e.extractTo("READMEXX.md", { password: "text", overwrite: true });
    // }
});

var file = zip.read("README.md", { password: "text" });
System.println(file);
zip.find("README.md")
    .extractTo("READMEXX.md", { password: "text", skip: true });

SQLite3

SQLite3 データベースの読み書きをサポート。トランザクションもサポート。何か他にも気にするところがあったような。。。SQLITE_BUSY が返ってきたときの挙動とかかな。追々確認しよう。今はこんな感じ。

import SQLite;

var db = new SQLite("database.db", 3000);
db.exec("CREATE TABLE IF NOT EXISTS mytable "
    "("
        "id INTEGER PRIMARY KEY AUTOINCREMENT, "
        "name TEXT NOT NULL"
    ")"
);
db.transaction(&{
    var ins = db.prepare("INSERT INTO mytable (name) VALUES (?)");
    for (var i = 0; i < 20; ++i) {
        ins.bind("name(%{i})").exec();
    }
});

var c, r = db.prepare("SELECT * FROM mytable WHERE (id > ? AND id < ?) OR id = ?")
            .bind(2)
            .bind(8, 10)    // bind() can be separated.
            .query();       // do binding & ready to next().

while (c = r.next()) {
    var cols = c.columnName;
    var vals = c.value;
    System.println("Record[%d]" % vals[0]);
    for (var i = 0, len = cols.length(); i < len; ++i) {
        System.println("    %-8s = %s" % cols[i] % vals[i]);
    }
}

Xml

Xml 文書の読み書きをサポート。XPath も使える。ちょっと長いがこんな感じ。

import Xml;

function displayXml(doc, node, indent) {
    System.print("  " * indent);
    if (node.type == Xml.ELEMENT_NODE) {
        System.print("ELEM %s" % node.name);
    } else if (node.type == Xml.TEXT_NODE) {
        System.print("TEXT %s" % node.value.trim());
    }

    var attr = node.attributes();
    for (var i = 0, len = attr.length(); i < len; ++i) {
        System.print("[%s=%s]" % attr[i].name % attr[i].value);
    }
    System.println("");

    var child = node.firstChild();
    while (child) {
        displayXml(doc, child, indent + 1);
        child = child.nextSibling();
    }
}

var doc = Xml.parseString(%{
<?xml version="1.0" encoding="UTF-8" ?>
<artists>
  <artist country="US" id="1">
    <name>BON JOVI</name>
    <price>2400</price>
    <img file="bonjovi.jpg"/>
  </artist>
  <artist country="US" id="2">
    <name>GUNS N ROSES</name>
    <price>21000</price>
    <img file="GNR.jpg"/>
  </artist>
  <artist country="DE" id="3">
    <name>Helloween</name>
    <price>2400</price>
    <img file="helloween.jpg"/>
  </artist>
</artists>
});
var root = doc.documentElement();
displayXml(doc, root);

var el = root.getElementById("3");
if (el) {
    el.remove();
}

System.println("");
System.println("getElementByTagName:");
var els = root.getElementByTagName("img");
if (els.isArray) {
    els.each(&(el) => displayXml(doc, el));
}

System.println("");
System.println("XPath:");
var nodes = doc.xpath("//car").xpath("price");
if (nodes.isArray) {
    nodes.each(&(el) => displayXml(doc, el));
}

var xmlWriter = new Xml.Writer(System);
xmlWriter.write(doc);
xmlWriter.write(root);

おわりに

だいぶ実用に近づいてきた。もうちょっとだから頑張ろう。ドキュメント書かないとね。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ドリルTX45 

class ArticlesController < ApplicationController

def show
article = Article.find(params[:id])
end
end

これでは表示されない、、、

Railsではコントローラで設定された「インスタンス変数」がビューに渡される仕組みになっている。

コードのarticleは通常のローカル変数であるためビューで使うことができない。そのため、articleを@articleに変更すればよい。

4行目のArticle.find(params[:id])という記述のうち、params[:id]には詳細表示されたいレコードのidが格納されます。なぜそのような動作になるのか、「rails routes」という言葉を使って説明してください。

rails routesを使ってアプリケーションのルーティングを確認すると、通常showアクションには以下のような設定がされている。

1 Prefix Verb URI Pattern Controller#Action
2 tweet GET /tweets/:id(.:format) tweets#show
そのため、例えば「localhost:3000/tweets/3」というURLが指定されると、paramsの「:id」というキーのバリューとして「3」が代入される。

そのため、そのあと呼び出されたコントローラー内でparams[:id]と取り出すことができる。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

rails sができない時の対処方

rails sを叩くとエラー出力

spring stopを試して解決できず少し詰まったので備忘録として残します。

/Users/arakitakuro/.rbenv/versions/2.5.1/lib/ruby/2.5.0/fileutils.rb:90: warning: already initialized constant FileUtils::VERSION
/Users/arakitakuro/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/fileutils-1.4.1/lib/fileutils.rb:105: warning: previous definition of VERSION was here
/Users/arakitakuro/.rbenv/versions/2.5.1/lib/ruby/2.5.0/fileutils.rb:1188: warning: already initialized constant FileUtils::Entry_::S_IF_DOOR
/Users/arakitakuro/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/fileutils-1.4.1/lib/fileutils.rb:1284: warning: previous definition of S_IF_DOOR was here
/Users/arakitakuro/.rbenv/versions/2.5.1/lib/ruby/2.5.0/fileutils.rb:1446: warning: already initialized constant FileUtils::Entry_::DIRECTORY_TERM
/Users/arakitakuro/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/fileutils-1.4.1/lib/fileutils.rb:1568: warning: previous definition of DIRECTORY_TERM was here
/Users/arakitakuro/.rbenv/versions/2.5.1/lib/ruby/2.5.0/fileutils.rb:1501: warning: already initialized constant FileUtils::OPT_TABLE
/Users/arakitakuro/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/fileutils-1.4.1/lib/fileutils.rb:1626: warning: previous definition of OPT_TABLE was here
/Users/arakitakuro/.rbenv/versions/2.5.1/lib/ruby/2.5.0/fileutils.rb:1555: warning: already initialized constant FileUtils::LOW_METHODS
/Users/arakitakuro/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/fileutils-1.4.1/lib/fileutils.rb:1685: warning: previous definition of LOW_METHODS was here
/Users/arakitakuro/.rbenv/versions/2.5.1/lib/ruby/2.5.0/fileutils.rb:1562: warning: already initialized constant FileUtils::METHODS
/Users/arakitakuro/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/fileutils-1.4.1/lib/fileutils.rb:1692: warning: previous definition of METHODS was here
=> Booting Puma
=> Rails 5.2.4.1 application starting in development 
=> Run `rails server -h` for more startup options
Puma starting in single mode...
* Version 3.12.4 (ruby 2.5.1-p57), codename: Llamas in Pajamas
* Min threads: 5, max threads: 5
* Environment: development
Exiting
Traceback (most recent call last):
    44: from bin/rails:3:in `<main>'
    43: from bin/rails:3:in `load'
以下略

原因

rails sしたままターミナルを閉じたのが原因でした。

解決方法

下記コマンドを入力し、出力されるPIDをコピー

lsof -i :3000 #PIDを確認

kill -QUIT PIDをペースト

これで解決しました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Ruby on Rails】フォームオブジェクトを使って検索キーワードをcontrollerに送る

想定対象者

  • Ruby on Railsで検索フォームを独自で作りたい
  • ransackを使いたくない
  • Google Books APIを使ったポートフォリオを作りたい(本記事ではあんまり関係ないけど)

(個人的に)実現したいこと

Google Books APIでは以下URLにキーワードを入れるだけで検索結果を返してくれるという仕様があります。
https://www.googleapis.com/books/v1/volumes?q=(ここにキーワード)

これを使えば、最終的に以下のようなViewの実装が思い浮かびます。
(ただし、この解説は別記事で予定)

books_controller.rb
@books = 処理(keyword)
>> [book1, book2, book3, ....]
search.html.slim
= @books.each do |book|
  = image_tag book.image
  = book.titile
  = book.author
  = ()

検索フォームを作るgemとしてransackという有名なgemがあります。
ただ、アプリのDB内で検索を行う目的で使われるもののようです。
本記事では、実際に検索を行うロジックはGoogle Books APIにキーワードを送るだけなので、ransackを使う必要がないことになります。
※まともにransackを使った経験があるわけではありません。

上記の実装をするには、まずは検索キーワードをcontrollerに持ってくる必要があります。
その際にはフォームオブジェクトを使うのが良いです。

フォームオブジェクトとActiveModel

まず、フォームオブジェクト is 何

参考:
form objectを使ってみよう
フォームオブジェクトでバリデーション 初心者→中級者へのSTEP2/25
(他にもフォームオブジェクトで検索するとたくさん出てきます)

本記事に当てはめれば、

  • form_withで検索キーワードだけをbooks#searchに送る
  • ActiveModelをincludeしたクラスを作る

ということになります。

ActiveModel is 何

誤解を恐れずに言うと、ActiveRecordのDBと連携しない版

ActiveRecordはDBへの連携以外でも、validateだったり、attributeだったり、便利な機能があると思います。
DBへの連携は必要ないが、Viewに対するこれらの機能は使いたい、というケースの場合にはActiveModelを使うべき、ということになります。
検索キーワードをcontrollerに送りたいだけでDBとは連携させない、本記事のケースのような場合には適切です。

参考:
【ruby】ActiveModelを使ってDBと関係ないFormを作成する【Rails】
ActiveModel::Attributes が最高すぎるんだよな。

用法としては以下の通り。

  1. app/forms/を作り、スネークケース.rbを置く
  2. class キャメルケースでクラスを定義する
  3. そのクラスにAcitveModelのモジュールをincludeする

参考: Railsガイドすごい!!!笑
Active Model の基礎

実装

具体的に本記事のやりたいことに当てはめると、以下のコードになります。

app/forms/search_books_form.rb
class SearchBooksForm
  include ActiveModel::Model
  include ActiveModel::Attributes

  attribute :keyword, :string
end
  • include ActiveModel::Attributesをしたことでattributeメソッドを使えます。
  • attribute :keywordと書けば、@search_form.keywordを使えます。
app/views/books/search.html.slim
= form_with model: @search_form, url: search_books_path, local: true, scope: q, method: :get do |f|
  .form-group
    = f.label :keyword, 'キーワード'
    = f.text_field :keyword, class: 'form-control', value: @search_form.keyword
  = f.submit '検索する'
app/controllers/books_controller.rb
  def search
    @search_form = SearchBooksForm.new(search_books_params)
    # @search_form.keywordに検索キーワードが渡ったので、以下色々なことしちゃいましょう
  end

  private

  def search_books_params
    params.fetch(:q, keyword: '').permit(:keyword)
  end

説明する前に力尽きたこと

  • 検索結果というリソースはURLとして持つべきという話
  • なぜGETメソッド使うのか
  • scope: :q is 何
  • fetch is 何
  • 「色々なことしちゃいましょう」の「色々なこと」(本当なら検索して結果をまとめるロジックを「色々なこと」に書きます)

参考:
【Ruby on Rails】require と permit の使い方がよく分からない

あとでこの記事を修正して書くモチベが生まれるかもしれませんし、生まれないかもしれません

教えてほしいこと

  • markdownでコード書いてるときに日本語部分の赤下線部破線を消す方法
  • フォームオブジェクトの説明ってこれで合ってるでしょうか
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ログインshellの変更、そしてrbenvでインストールしたRubyをデフォルトにする方法

ゴールはrbenvでインストールしたRubyをデフォルトで開けること。
→その設定が書かれた.bash_profileというファイルを
 デフォルトで読み込んでもらえないというのが問題でした。

前回記事
https://qiita.com/hacchi_mom/items/2095e6ac7aecd03f131a

.bash_profileについて

まず.bash_profileってなんなんだというところから調べると
【ログインの際に読み込まれる設定ファイル】とのこと。

そして重要なのは、その設定ファイルは
【ログインshellがbashのときに読み込まれるもの】
ということ!!!!

ログインshell問題

ログインshellとはログイン時に起動するshellのことですが
そもそも私の起動時のログインshellはbashではなくzshだったのです。

Terminal起動時に毎回まずbashと一度打ってから
全ての作業を始めておりました…そういうもんだと思っていました。笑

初歩すぎること書いててすいません。。。
だから.bash_profileを読み込んでもらえなかったんですね。

ログインshellの変更への道

まずは以下のコマンドでbashを使う指示をしてみる。

$ chsh -s /usr/local/bin/bash
chsh: /usr/local/bin/bash: non-standard shell

早速拒否されたので笑
まず変更できるshellの一覧を出してみる。

$ cat /etc/shells
# List of acceptable shells for chpass(1).
# Ftpd will not allow users to connect who are not using
# one of these shells.

/bin/bash
/bin/csh
/bin/dash
/bin/ksh
/bin/sh
/bin/tcsh
/bin/zsh

先ほどのコマンドを有効にするためには、
この/etc/shellsというファイルに
/usr/local/bin/bashを追記しなければならないそうです。

そしてそのファイルに書く手段として検索して出てきたのが【vim】

正直初心者には操作性が難しすぎた…

私にはvim以外の書き方を検索する力がなく、
以下のリンクを参考にして奇跡的に書けました。
https://original-game.com/vim-mac2/#m_heading-1

※vimについてはまだ説明できる力がないので割愛します。。
 Finderでファイル名検索とかしても非表示ファイルだから出てこないですが、
 エディタで編集する方法も調べればありそうです!

そしてもう一度、変更できるshellの一覧

$ cat /etc/shells
# List of acceptable shells for chpass(1).
# Ftpd will not allow users to connect who are not using
# one of these shells.

/usr/local/bin/bash  ← これが無事追加されました!
/bin/bash
/bin/csh
/bin/dash
/bin/ksh
/bin/sh

そしてもう一度、最初に打ったbashを使う指示のコマンド

$ chsh -s /usr/local/bin/bash
chsh: WARNING: shell '/usr/local/bin/bash' does not exist
chsh: no changes made

さっきとエラー文が変わった!

これを調べるとコマンドではなく
ターミナル >環境設定 >一般 のなかに
【開くシェル】という設定がありました!

これをデフォルト → コマンドに設定を変更し、
以下の画像のように/bin/bashと打ち込みます。

スクリーンショット 2020-03-04 23.56.13.png

これで最後にもう一度最初のコマンドを

$ chsh -s /usr/local/bin/bash
Changing shell for local.
Password for local:

(↑ちなみに最初の2回は割愛しましたが
このコマンド打つと毎回パスワードを求められます。)

そしてターミナルを再起動すると
ログインshellはbashになっていました!

そして私のゴールだったRubyは…

$ which ruby
/Users/local/.rbenv/shims/ruby

できました!
これでrbenvでインストールしたRubyがデフォルトになりました。

参考記事

https://wa3.i-3-i.info/word13650.html
https://teratail.com/questions/59821
https://www.task-notes.com/entry/20150117/1421482066
https://qiita.com/n_oshiumi/items/5ea418bed44fb81dd653
https://creepfablic.site/2019/10/13/bash-zsh/#index_id4

たくさんの記事に助けられました!
長々と読んでくださった方、ありがとうございました!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Rails環境下でembulkを使って快適に数十万件のデータを取り込む

こんばんわ。人に裏切られるのと同じくらいの仕打ちを受けて、最近意気消沈しているプレイライフエンジニアの合原です。

今回は弊社でのembulkの活用事例について、まとめます。

embulk活用前

弊社では、特集記事や遊びのプラン記事では、グルメやホテルの紹介もあり、漏れなく、アフィリエイト広告(以降アフィリエイト)を掲載しています。


https://play-life.jp/articles/1550
https://play-life.jp/articles/1510

こういった感じで。
また、日本全国には、グルメ・ホテルなど、数えきれないほどの店舗数があり、自ずと、各種アフィリエイト用の店舗データも大量なものとなります。
にも関わらず、embulkの活用前までは、rubyで何万ー何十万と言うデータをinsert, updateと。。。やっている始末でした。

こんな時こそのembulk

embulkです。
スクリーンショット 2020-03-04 23.28.16.png

大量のデータ転送ツールで有名なembulkにはフィルタリング、パーサー等のプラグインも充実していて、データのI/Oが柔軟にできるようになります。

スクリーンショット 2020-03-04 23.32.22.png

従来のやり方は何が問題だったのか?

  • 時間がかかる
  • 何よりもテストがない

データある分だけループしつつ、 insertupdateとやっているので、これは多くを語らずとも...なかなかに辛い状況が想像しやすいかと思います。
また、データによっては、クライアントのAPIを経由して取得するデータもあるが、その場合のケアが全くないと言う状態もあり。

まずは設計

何はともあれまずは設計です。
どう攻めるか。

まず、使用経験もあったことから、時間のコストについては、真っ先にembulkを採用しようとなりました。
あとは、embulkをどう実行するか。

端的に言えばembulkに任せたいのは、
* データ転送(投入)

のみ
投入するデータの取得自体は、APIを叩けば取得できる。つまり、ここをスクリプト(ruby)で、かつ、テストもする形すれば...
と言うことで、手順を改めて整理すると、

  1. スクリプト(ruby)で投入データの取得
  2. embulk で1をDBへ投入

と、方針を決定。

(少し寄り道)データ転送は本来どこでやるべき?

本来であれば、サービス環境とデータのETL(Extract(抽出) Transform(変換) Load(格納)の環境が別れて存在しているのが理想でした。そうあれば、ETL環境で外部からの

  1. スクリプト(ruby)で投入データの取得
  2. embulk で1を(サービス環境側の)DBへ投入

ができたので。
が、弊社もまだまだスタートアップということで贅沢は言ってられないため、この点は一旦目を瞑りました。

早速embulkをRails環境下で使う

ここからは普段通りのRails環境下での開発です。
手順としては、

  1. データの取得を行う(model)を用意する
  2. 上記のテストを書く
  3. データの投入を行うembulkの設定ファイルを用意する
  4. embulkを実行するrake task を用意する

rakeタスクでデータ取得を行うのでなく、それをするmodelを使うこととしているのは、そのmodelのテストがしやすくなるからです。また、こうすることで、rakeタスクでは決められた手順でmodelを呼び出すだけ済みます。

Rails環境下で使うembulkの構成

RailsApps直下にembulkディレクトリを用意して、下記のような構成で配置します

$ ./rails_apps(master)

embulk
├── config.yml.sample
├── hogehoge_restaurant_plans
└── hogehoge_restaurant_plans_import.yml.liquid

対象となるデータインポート内容に応じて、誰が見てもわかりやすいような名前でディレクトリ(hogehoge_restaurant_plans)と、そのembulkの設定ファイル(hogehoge_restaurant_plans_import.yml.liquid)を用意します。

例) hogehoge_restaurant_plans_import.yml.liquid

{% include 'hogehoge_restaurant_plans/in' %}
{% include 'hogehoge_restaurant_plans/filters' %}                                                                                                                                     
{% include 'hogehoge_restaurant_plans/out',
   db_host: env.DB_HOST,
   db_name: env.DB_NAME,
   db_user: env.DB_USER,
   db_password: env.DB_PASSWORD %}

ご覧のようにin, filter, outそれぞれの設定ファイルは、メンテもしやすくするためにも上記で作ったディレクトリの方に、下記のように用意します。(下記)
ポイントは各種liquidファイルを分け、includeする形にすることです。

hogehoge_restaurant_plans
├── Gemfile
├── Gemfile.lock
├── _filters.yml.liquid
├── _in.yml.liquid
├── _out.yml.liquid
├── embulk
├── src
└── vendor

※詳細については本記事では割愛しますが、別記事にて embulkの詳細な使い方については、まとめます。

最終的な利用方法

あとはrakeタスクを用意して、定期実行(cronなり)設定すれば使えるようになります。

task shops_download: :setup_logger do
    logger.info 'Start download hogehoge_restaurant_shops: :setup_logger'
    Dir.chdir('./embulk/hogehoge_restaurant_shops/src') do
      fetcher = Affiliates::HogeRestaurants::PlanFetcher.new(local: Rails.env.development?)
      fetcher.execute
    end
    logger.info 'Finished download hogehoge_restaurant_shops: :setup_logger'
  end
  desc 'Bundle install hogehoge_restaurant shops'
  task bundle_install: :setup_logger do
    logger.info 'Bundle hogehoge_restaurant_shops: :setup_logger'
    Dir.chdir('./embulk/hogehoge_restaurant_shops') do
      sh %(embulk bundle --path=vendor/bundle)
    end
    logger.info 'Finished bundle hogehoge_restaurant_shops: :setup_logger'
  end
  :
  desc 'Import hogehoge_restaurant shops'
  task import_shops: :setup_logger do
    logger.info 'Import_hogehoge_restaurant_shops: :setup_logger'
    Dir.chdir('./embulk') do
      sh %(export DB_HOST=localhost;
            export DB_NAME="#{db_config['database']}";
            export DB_USER="#{db_config['username']}";
            export DB_PASSWORD=#{db_config['password']} ;
            embulk run hogehoge_restaurant_shops_import.yml.liquid -b hogehoge_restaurant_shops/
      )
      logger.info 'Finished import_hogehoge_restaurant_shops: :setup_logger'
    end
  end
end

:

def db_config
  file_path = Rails.root.join('config', 'database.yml')
  YAML.load_file(file_path)[Rails.env]
end

まとめ

rubyで長時間におよぶループをして、時間をかけていた点が解決しただけでなく、embulkを比較的にスマートにRails環境下で使える形にできたかと思います。
今回紹介した例はあくまで一例ですが、以降は、同様の形で、弊社ではさまざまな用途でembulkを活用していっています。
その辺りの話はまた今度。

embulkの活用方法など、もっといい方法があれば是非ともご連絡お願いします。それでは、また次記事にて。。。,

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む