RHEL7でRailsアプリのサーバを構築した【Rubyのインストール・設定】

こちらは、

RHEL7でRailsアプリのサーバを構築した - takapiのブログ

Rubyのインストール・設定 に関する記事です。

takapi86.hatenablog.com

インストール済みの Ruby の削除

EC2のRHEL7では、元々インストールはされていませんでしたが、環境によってはデフォルトでRubyが入っている場合があります。 ほとんどの場合は、古いRubyが入っているので、一旦削除してしまいましょう。

$ sudo yum -y remove ruby

gitをインストールする

後ほど、 rbenv,ruby-build といったツールをダウンロードするのに必要です。

$ sudo yum -y install git

rbenvをインストールする

Rubyのバージョンの切り替えなどが簡単にできるツールであるrbenvをインストールします。 以下のサイトを参考にインストールします。

https://github.com/rbenv/rbenv

クローンします。

$ git clone --depth 1 https://github.com/rbenv/rbenv.git

.bash_profile に PATHを通します。

$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile

echo 'eval "$(rbenv init -)"' >> ~/.bash_profile で何をしているかは、 こちらを参考にするとよいでしょう。

takatoshiono.hatenablog.com

一度、ログアウトし直すか、以下のコマンドで ~/.bash_profile を読みなおします。

$ source ~/.bash_profile

rbenv コマンドが使えるか確認します。

$ rbenv
rbenv 1.1.1-2-g615f844
Usage: rbenv <command> [<args>]

Some useful rbenv commands are:
   commands    List all available rbenv commands
   local       Set or show the local application-specific Ruby version
   global      Set or show the global Ruby version
   shell       Set or show the shell-specific Ruby version
   rehash      Rehash rbenv shims (run this after installing executables)
   version     Show the current Ruby version and its origin
   versions    List all Ruby versions available to rbenv
   which       Display the full path to an executable
   whence      List all Ruby versions that contain the given executable

ruby-buildをインストールする

rbenv の プラグインである ruby-build をインストールします。 実際にRubyコンパイルしてインストールしてくれるものです。

クローンします。

$ git clone --depth 1 https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build

もう一度、rbenvコマンドを実行します。

$ rbenv
rbenv 1.1.1-2-g615f844
Usage: rbenv <command> [<args>]

Some useful rbenv commands are:
   commands    List all available rbenv commands
   local       Set or show the local application-specific Ruby version
   global      Set or show the global Ruby version
   shell       Set or show the shell-specific Ruby version
   install     Install a Ruby version using ruby-build
   uninstall   Uninstall a specific Ruby version
   rehash      Rehash rbenv shims (run this after installing executables)
   version     Show the current Ruby version and its origin
   versions    List all Ruby versions available to rbenv
   which       Display the full path to an executable
   whence      List all Ruby versions that contain the given executable

ruby-build をクローンする前になかった install,uninstall が表示されていれば成功です。

Ruby2.4.1をインストール

EC2のRHEL7では、Rubyコンパイルに以下のライブラリが必要なのでインストールしておきます。

$ sudo yum install -y gcc bzip2 openssl-devel readline-devel zlib-devel

Rubyコンパイル・インストールします。

rbenv install 2.4.1

スペックによりますが、結構時間がかかるので待ちます。

インストールしたRuby2.4.1を使うので、以下のコマンドで使えるようにします。

rbenv global 2.4.1

Rubyがインストールされているか確認する。

ruby -v
ruby 2.4.1p111 (2017-03-22 revision 58053) [x86_64-linux]

以上でRuby のインストールは完了です。

自宅のubuntu-16.04マシンのシェルをfishに変更した

自宅のubuntu-16.04マシンのシェルをfishに変更したので手順をメモしておきます。

また、pecoとの連携もしていきます。

fish をインストール

sudo apt-add-repository ppa:fish-shell/release-2
sudo apt-get update
sudo apt-get install fish

apt-add-repository コマンドがない場合は以下の手順で導入します。

sudo apt-get install apt-file
sudo apt-file update
sudo apt-get install software-properties-common

fish をデフォルトシェルにする

追記:

fish はデフォルトシェルにしないほうが良いんじゃないかなー。というのをこちらのエントリーに書きました。 良ければ見てください。 fish をデフォルトシェルに設定しない - takapiのブログ

chsh -s /usr/bin/fish

端末を開き直し、 echo $SHELL コマンドで確認します。

echo $SHELL
/usr/bin/zsh

あれ・・・

GUI環境の場合は一度ログアウトしてあげる必要がありそうです。

echo $SHELL
/usr/bin/fish

fishになっていることを確認しました。

fish の基本設定

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

mkdir -p ~/.config/fish

初期設定ファイルを作成します。

vim ~/.config/fish/config.fish

~/.config/fish/config.fish へ以下のようにPATHを追加します。

set -g -x PATH /usr/local/bin $PATH

oh-my-fish をインストール

git がない場合はインストールしておきます

sudo apt-get install git

以下のcurlコマンドで oh-my-fish をインストールします。 ※直接シェルスクリプトを実行するので、中身は必ず確認しておいてください。

curl -L http://get.oh-my.fish | fish

以下のコマンドを打つと、ブラウザが立ち上がり、 fishの設定をGUIで変更できるようになります。

fish_config

私は、 colorfish defaultpromptAcidhub にしました。

peco をインストール

cd ~
wget https://github.com/peco/peco/releases/download/v0.5.1/peco_linux_amd64.tar.gz
tar zxvf peco_linux_amd64.tar.gz
sudo cp peco_linux_amd64/peco /usr/local/bin/
sudo chmod 777 /usr/local/bin/peco

peco と fish の連携

こちらの記事を参考にしました。 https://www.key-p.com/blog/staff/archives/105041

pecoプラグインをインストールします。

omf install peco

~/.config/fish/config.fish に以下を追加します。

#peco
function fish_user_key_bindings
    bind \cr peco_select_history
end

コンソールを開き直すなどし、設定ファイルを読み直したあとに Ctrl + r を押すといい感じに履歴とpecoが連携してくれます。

以上で、fish、pecoのインストールは完了です。

参考サイト

Rubyのバージョンを上げたときの手順メモ

自端末と自作サービスのRubyのバージョンを2.4.1へ上げたのでそのときのメモを残しておきます。

rbenvとruby-buildの更新

自分はRubyのバージョン管理をrbenvで行っているので、まず、rbenvの更新します。

rbenvを更新

cd ~/.rbenv
git pull origin master

ruby-buildを更新

cd ~/.rbenv/plugins/ruby-build
git pull origin master

Ruby 2.4.1 をインストー

rbenv install 2.4.1

端末のスペックによってそれぞれですが、結構時間がかかります。

Ruby 2.4.1 を設定

環境全体への設定

rbenv global 2.4.1

自作サービスのRubyバージョンも設定しておきたいので、以下のコマンドで .ruby-version を作成します。

rbenv local 2.4.1

バージョンが上がっている確認

以下のコマンドでバージョンが上がっているか確認できます。 .ruby-version があるディレクトリで実行した場合は .ruby-version で設定されている値が優先されます。

ruby -v       
ruby 2.4.1p111 (2017-03-22 revision 58053) [x86_64-linux]

以上でRubyのバージョンアップは完了です。

AngularJS1.6に上げたらルーティング時のパスがhash (#/)からhash-bang (#!/)になっていた

AngularJS1.6に上げたらルーティング時のパスがhash (#/)からhash-bang (#!/)になっていた

自己学習用に作成していたAngularJS 1.4アプリをAngularJS 1.6 に上げた際に、 ルーティング時のパスがhash #/ からhash-bang #!/ に変換されるようになってしまい、うまくルーティングが働かなくなってしまう問題に遭遇しました。 対応したのでメモとして残しておきます。

現象

以下のURLに直接またはリンクから遷移しようとしたとき、例えば以下のような

http://localhost:9000/#/search

にすると、ルーティング定義したページを表示して欲しいのですが、

http://localhost:9000/#!/#%2Fsearch

上記のように自動的にスラッシュが %2F 変換され、hash-bang #!/ が追加されます。 自分の環境では、上記のURLはルーティング定義していないので、 otherwise に設定しているページに遷移されるようになってしまいました。

ちなみに、ルーティングの定義は以下のように行っています。

.when('/search', {
  templateUrl: 'views/search.html',
  controller: 'SearchCtrl',
  controllerAs: 'search'
})
.otherwise({
  redirectTo: '/'
});

原因

AngularJS 1.6が $location サービスのURLのデフォルト値を変更したことが原因です。

Googleクローラー対策みたいです。(#!/を使用することを推奨している。)

ちなみに、以下のコミットで修正されています。 https://github.com/angular/angular.js/commit/aa077e81129c740041438688dff2e8d20c3d7b52

解決方法1

リンクのURLの#のあとに!を加えるようにします。 これが一番素直な解決方法かと。私はこちらで対応しています。

<a ng-href="#/search">Search</a>

を以下のように#/#!/にしてあげます。

<a ng-href="#!/search">Search</a>

解決方法2

AngularJS 1.6 以前と同じく #/ でいけるようにするには、 $locationProvider.hashPrefix('') を設定することで対応できます。

appModule.config(['$locationProvider', function($locationProvider) {
  $locationProvider.hashPrefix('');
}]);

参考

https://docs.angularjs.org/guide/migration#commit-aa077e8 https://github.com/angular/angular.js/commit/aa077e81129c740041438688dff2e8d20c3d7b52 http://stackoverflow.com/questions/41211875/angularjs-1-6-0-latest-now-routes-not-working http://stackoverflow.com/questions/41272314/angular-all-slashes-in-url-changed-to-2f

Gemに渡す町コードを一括保存するバッチを作成した

先日、以下の記事で紹介した、ごみ収集曜日を取得する処理をGemへ渡すためのコードを取得するバッチを作成しました。

takapi86.hatenablog.com

なぜ作成したか。

先日書いた記事でも紹介しましたが、このGemでごみ収集曜日を取得するためには以下のパラメータとして以下のコードを渡す必要があります。

しかし、上記コードを見つけるためには、実際に横浜市のHPにアクセスし、URLを確認してパラメータを設定しなければなりません。 それだと、そもそも横浜市のHPにアクセスしているので「普通にで確認すれば良いじゃん」になるので、一括で上記コードを取得し、DBに保存するバッチを作成しました。

ページの構造

ごみ収集曜日のページ(横浜市資源循環局)は以下のような階層構造になっています。

収集曜日ページのトップです。区を選択することができます。 区の名前をクリックすると、その区の町名の頭文字を選択する画面に遷移します。

  • 頭文字の選択ページ

例:港北区(区コード:16) http://cgi.city.yokohama.jp/shigen/kaishu/mobile/16

町(収集場所)の頭文字を選択する画面です。以下のような構成で各行ごとにリンクが貼られています。

[1] あ~お
[2] か~こ
[3] さ~そ
[4] た~と
[5] な~の
[6] は~ほ
[7] ま~も
[8] やゆよ
[9] ら~ろ、わ
  • 町名の選択ページ

例:港北区(区コード:16) さ行(頭文字コード:3) http://cgi.city.yokohama.jp/shigen/kaishu/mobile/16/3

選択した区の選択した行(あかさたな)に該当する町名一覧が表示されます。

港北区のさ行では、以下の一覧が表示されます。

町名にリンクが貼られており、クリックすると、該当の町の収集曜日が表示されます。

篠原北1丁目
篠原北2丁目
篠原台町
篠原町
篠原西町
篠原東町1丁目
篠原東町2・3丁目
下田町1・2・3丁目
下田町4・5・6丁目
新横浜1・2・3丁目
新吉田町
新吉田東1~6丁目
新吉田東7・8丁目
  • ごみ・資源物の収集日ページ

ここで、ごみ・資源物の収集日を確認することができます。

例:港北区(区コード:16) さ行(頭文字コード:3) 町コード 1073 http://cgi.city.yokohama.jp/shigen/kaishu/mobile/16/3/1073

Gemは、このURLを見てページからごみ収集曜日を取得します。

バッチの取得対象

先述した通り、

がわかれば、ごみ収集曜日を取得することができるので、 区から町名を選択する画面まで、リンクに含まれる各コードと名称を取得しながら再帰的にデータを取得していきます。

収集場所までバッチで持ってくれば良いのでは?とお思いの方もいらっしゃると思うのですが、 すべてのページのデータを持ってくるためには、 18区×あかたたな(9行)×町名分必要であり、横浜市のサーバへかなりのリクエストが発生してしまうため含めておりません。

あとは、もうGemつくちゃったしな・・・と、なんかすいません。といった感じです。

また、負荷については怒られないように、配慮していてバッチ内では5秒一回しかリクエストを飛ばさないようにしています。

作ってみた所感

今回は、基本となる機能は雑に一気に仕上げ、それから例外処理の追加やリファクタリングをしていくという流れで実装していきました。 ほぼ勢いで実装しましたが、丁寧に積み上げていく方式よりも自分の感覚的に合っているなと感じました。

というのは、処理を書く上で色々考えなければならないことがシンプルになるということ * Rubyっぽく書くには * クラスをどう分ける? * わかりやすい変数名は?

と、普段は実装する上で同時に考えることが多いので、まず一気に仕上げてから細かい部分を調整していくやり方にしてみて、こっちの方が性にあっているのでは?という気持ちになっていますす。(精神的にも疲れにくく、集中して取り組めたのではないかと感じました。)

すべてのケースには当てはまらないと思いますが、実装の仕方はこれからも試行錯誤しながらやっていきたいと思います。

ごみ収集曜日を取得する処理をGem化した

ごみ収集曜日を取得する処理だけを切り出し、Gem化したので、使い方をメモしておきます。

機能は随時更新していく予定です。

どのようなGemか?

横浜市資源循環局のページから、ごみ収集曜日の情報を取得しHashの配列で返します。

データ量の少ないモバイル版から取得しています。 http://cgi.city.yokohama.jp/shigen/kaishu/mobile/

使い方

例えば、港北区篠原町の収集曜日は以下のURLです。 http://cgi.city.yokohama.jp/shigen/kaishu/mobile/16/3/1073

区、頭文字、町名にそれぞれコードが振られており、上記URLの場合は、

  • 区: 16
  • 頭文字: 3
  • 町名: 1073

になっています。

情報を取得するには、 Yokohama::Gomi::Schedule::App#fetch_schedule メソッドを叩く必要があり、 引数にそれぞれ区、頭文字、町名、 ward_id:,initial_code,town_id を指定します。

戻りは、取得した曜日(漢字)に対して、曜日に応じたごみの情報が入ったHashの配列(月〜土)で返ってきます。

作ってみて

Gemを作成するのは初めてでしたが、 bundle gem コマンドを使うことで簡単に作成することができました。 現在は区、頭文字、町名のコードをがわかっていないと使えないので、今後は文字列から各コードを参照するような機能などを追加していきたいと思います。

DatabaseRewinderを追加した

【ごみ収集曜日APIシリーズ】FactoryGirlを追加した - takapi86のブログ

の続きです。 前回は、テストを2回目実行しようとすると、ユニーク制約に引っかかりエラーになってしまう問題が残ってしまいました。 今回はその対応として、DatabaseRewinderというGemを使い、Rspecのテスト後に、 Createで作成したTestデータをデータベースから削除するようにしていきます。

github.com

上記のREADME.mdを参考にし導入しました。

導入

Gemfiledatabase_rewinder を追加して、bundle installします。

テスト環境のみで使用するので、 grouptest だけでよいでしょう。

group :test do
  gem 'database_rewinder'
end

rails_helper に以下の記述を追加します。

複数DBを扱うわけではないので、基本的な設定でいきます。

RSpec.configure do |config|
  config.before(:suite) do
    DatabaseRewinder.clean_all
  end

  config.after(:each) do
    DatabaseRewinder.clean
  end
end

試してみる

データがない状態で確認をしたいので、 以下のコマンドで、DBをリセットしておきます。

RAILS_ENV=test bundle exec rake db:migrate:reset

実行してみます。

bundle exec rspec spec/requests/towns_spec.rb
..

Finished in 2.18 seconds (files took 3.28 seconds to load)
2 examples, 0 failures

bundle exec rspec spec/requests/towns_spec.rb
..

Finished in 1.43 seconds (files took 3.2 seconds to load)
2 examples, 0 failures

データを見てみます。

[1] pry(main)> Town.all
  Town Load (3.0ms)  SELECT "towns".* FROM "towns"
=> []
[2] pry(main)>

2回以上実行しても、正常に動作し、テスト後のデータもすべてクリアされていました。

バッと書いてしまいましたが、今回はこんなところで。