Ruby on Rails チュートリアルの要約「第1章 ゼロからデプロイまで」

よこのじ(@yokonoji_work)です。

Ruby on Rails チュートリアル「第1章 ゼロからデプロイまで」の要約記事です。

第1章 ゼロからデプロイまで の要約

Railsチュートリアルは、Rubyの基礎、HTMLとCSS、データベース、バージョン管理、開発技法などWeb開発のすべてが網羅されている。

学べること

  • MVC
  • REST
  • ジェネレータ
  • マイグレーション
  • ルーティング
  • ERB など

各章で行うこと

1章では、開発環境を構築して、hello_appを作成する。
また、Gitでのバージョン管理や本番環境へのデプロイまで行う。

2章では、scaffoldを使ってtoy_appを作成する。

3章以降では、大規模なアプリケーションsample_appを作成する。
scaffoldによる自動生成コードは使わない。

  • 3章:静的ページを作成して、動的な要素を追加
  • 4章:Rubyについての学習
  • 5~12章:レイアウト、ユーザーのデータモデル、ユーザー登録と認証システム
  • 13~14章:マイクロブログ機能とソーシャル機能の実装

1.1 はじめに

Ruby on Railsは、Rubyで記述された、Web開発フレームワーク。デビューは2004年。

Airbnb や Basecamp, Disney, GitHub, Hulu, Kickstarter, Shopify, Twitter, Yellow Pages などの企業がRailsを採用した。

Railsはオープンソースで、アイデアを積極的に取り入れるコアチームと多くのコントリビューターがいることでgem開発が進むなどのコミュニティの強さがある。

1.1.1 前提知識

チュートリアルで必須の前提知識はない。Rubyやminitest (Railsのテストフレームワーク) 、HTML、CSS、JavaScriptとSQLの説明も含まれるため。

チュートリアルはプログラミング経験者を対象としているため、未経験者は先にProgateで学ぶと良い。

演習

  1. Ruby on Railsで使うRuby gemはどのWebサイトにありますか?ヒント: 分からないときはとにかくググりましょう。
    =>https://rubygems.org/
  2. 現時点でのRailsの最新バージョンはいくつですか?
    =>5.2.3  https://rubyonrails.org/
  3. Ruby on Railsはこれまでに何回ダウンロードされたでしょうか?調べてみてください。
    =>累計:174,355,524/5.2.3:1,108,357 (2019.05.25時点) https://rubygems.org/gems/rails

1.1.2 この本における取り決め

コマンドは行頭に$を付けて表記。

エラーが出た場合はググったり、RailsチュートリアルのHelpページで調べること。

1.2 さっそく動かす

開発環境の違いにより様々な問題は発生するため、Learn Enoughでの学習の中で環境構築する。または、クラウドIDE(クラウド統合開発環境)の利用がおすすめされている。

1.2.1 開発環境

環境構築の複雑さを避けるためにAWS Cloud9の利用がおすすめ。

RubyやRubyGems、Gitなど、Railsの開発環境の構築に必要なソフトウェアがほとんど組み込まれている。

その他で環境構築する場合の参考ページ

Vagrant, VirtualBox, Ubuntuで環境構築した記事を書いていますので、ご参考に。

Ruby on Railsの環境構築 その1 VagrantとVirtualBoxの理解とインストール

AWS Cloud9はAmazonのサービスで、1年間無料で利用できる。期限が切れたとしても、利用した分だけの課金方式。利用量によるけど、1ヶ月200円くらいで使える。

登録方法は「1.2.1 開発環境」を参考にしてください。

1.2.2 Railsをインストールする

Rubyドキュメントのインストールで無駄な時間を使わないように、このコマンドを最初に打っておくと良いらしい。

$ printf "install: --no-document \nupdate:  --no-document\n" >> ~/.gemrc

そして、gemコマンドを使ってrailsをインストールする。-v オプションでバージョンを指定している。

$ gem install rails -v 5.1.6

1.3 最初のアプリケーション

手始めにHello Worldを表示するアプリケーションを作るので、専用の「environment」ディレクトリを作る。

$ cd                               # ホームディレクトリに移動する
$ mkdir environment    # 'environment' ディレクトリを作成する
$ cd environment/        # 'environment' ディレクトリに移動する

その他、基本的なコマンド

ディレクトリ内容の表示 ls
ディレクトリの作成 mkdir <ディレクトリ名>
ディレクトリの移動 cd <ディレクトリ名>
上のディレクトリに移動 $ cd ..
ホームディレクトリに移動 $ cd ~ もしくは $ cd
ホームディレクトリ直下のenvironmentに移動 $ cd ~/environment/
ファイルの移動やリネーム mv <移動元> <移動先>/mv <現在の名前> <変更後の名前>
ファイルのコピー cp <コピー元> <コピー先>
ファイルの削除 rm <ファイル名>
空のディレクトリの削除 rmdir <ディレクトリ名>
中身のあるディレクトリの削除 rm -rf <ディレクトリ名>
ファイルの内容の結合と表示 cat <ファイル名>

rails newコマンドを実行する。

$ cd ~/environment
$ rails _5.1.6_ new hello_app

hello_appのディレクトリが表示されないなと思ったら、ディレクトリの表示にチェックが付いていないようだった。

rails new後のフォルダ確認

作成されたディレクトリと用途

app/ モデル、ビュー、コントローラ、ヘルパーなどを含む主要なアプリケーションコード
app/assets アプリケーションで使うCSS (Cascading Style Sheet)、JavaScriptファイル、画像などのアセット
bin/ バイナリ実行可能ファイル
config/ アプリケーションの設定
db/ データベース関連のファイル
doc/ マニュアルなど、アプリケーションのドキュメント
lib/ ライブラリモジュール
lib/assets ライブラリで使うCSS (Cascading Style Sheet)、JavaScriptファイル、画像などのアセット
log/ アプリケーションのログファイル
public/ エラーページなど、一般(Webブラウザなど)に直接公開するデータ
bin/rails コード生成、コンソールの起動、ローカルのWebサーバの立ち上げなどで使うRailsスクリプト
test/ アプリケーションのテスト
tmp/ 一時ファイル
vendor/ サードパーティのプラグインやgemなど
vendor/assets サードパーティのプラグインやgemで使うCSS (Cascading Style Sheet)、JavaScriptファイル、画像などのアセット
README.md アプリケーションの簡単な説明
Rakefile rakeコマンドで使えるタスク
Gemfile このアプリケーションに必要なGemの定義ファイル
Gemfile.lock アプリケーションで使われるgemのバージョンを確認するためのリスト
config.ru Rackミドルウェア用の設定ファイル
.gitignore Gitに取り込みたくないファイルを指定するためのパターン

このようにディレクトリ構造が決まっているから誰がやっても同じでコードを読みやすくなっている。

1.3.1 Bundler

rails newを行ったときにbundle installが実行されて、必要なgemがインストールされている。

バージョン情報はGemfileに書かれており、これを修正してBundlerを再実行するとgemのバージョンを変更できる。

gem ‘uglifier’, ‘>= 1.3.0’ であれば、1.3.0以上の最新バージョンがインストールされる。
gem ‘coffee-rails’, ‘~> 4.0.0’ であれば、4.0.0より大きく、4.1より小さいバージョンをインストールする。

チュートリアルでは、バージョン違いによる不具合をなくすために次の内容にGemfileを書き換えることをおすすめしている。

source 'https://rubygems.org'

gem 'rails',        '5.1.6'
gem 'puma',         '3.9.1'
gem 'sass-rails',   '5.0.6'
gem 'uglifier',     '3.2.0'
gem 'coffee-rails', '4.2.2'
gem 'jquery-rails', '4.3.1'
gem 'turbolinks',   '5.0.1'
gem 'jbuilder',     '2.6.4'

group :development, :test do
  gem 'sqlite3',      '1.3.13'
  gem 'byebug', '9.0.6', platform: :mri
end

group :development do
  gem 'web-console',           '3.5.1'
  gem 'listen',                '3.1.5'
  gem 'spring',                '2.0.2'
  gem 'spring-watcher-listen', '2.0.1'
end

# Windows環境ではtzinfo-dataというgemを含める必要があります
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

Gemfileを書き換えたら、bundle installする。

$ cd hello_app/
$ bundle install

私の場合はbundle installの最後でこのような注意をされたので、メッセージのとおりにbundle update コマンドを実行した。

Bundler could not find compatible versions for gem
“activesupport”:
In snapshot (Gemfile.lock):
activesupport (= 5.1.7)

In Gemfile:
rails (= 5.1.6) was resolved to 5.1.6, which depends
on
activesupport (= 5.1.6)

coffee-rails (= 4.2.2) was resolved to 4.2.2, which
depends on
railties (>= 4.0.0) was resolved to 5.1.7, which
depends on
activesupport (= 5.1.7)

Running `bundle update` will rebuild your snapshot from
scratch, using only
the gems in your Gemfile, which may resolve the conflict.

1.3.2 rails server

アプリケーションをローカルWebサーバーで起動させるためにrails serverコマンドを実行します。

$ cd ~/environment/hello_app/
$ rails server

終わったらCloud9の場合は上のPreview => Preview Running Application =>開いたウインドウでポップアップボタンを押すとYay! You’re on Rails!の画面が表示されます。

画面に表示のバージョン情報

Rails version: 5.1.6
Ruby version: 2.6.3 (x86_64-linux)

演習

  1. デフォルトのRailsページに表示されているものと比べて、今の自分のコンピュータにあるRubyのバージョンはいくつになっていますか? コマンドラインでruby -vを実行することで簡単に確認できます。
    ▶ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-linux]
  2. 同様にして、Railsのバージョンも調べてみましょう。調べたバージョンはリスト 1.1でインストールしたバージョンと一致しているでしょうか?
    ▶cd ~/enviroment/hello_app の後 Rails -v すると、Rails 5.1.6でGemfileで指定したバージョンと同じだった。

1.3.3 Model-View-Controller (MVC)

RailsはMVC (model-view-controller) というアーキテクチャパターンを採用している。MVCでは、アプリケーション内のデータ(ユーザー情報など)と、データを表示するコードが分離されている。

  • Railsアプリと通信する際、ブラウザはWebサーバーにリクエスト (request) を送信して、Railsのコントローラ (controller) に渡される。
  • 静的サイトであれば、コントローラはすぐにビュー (view) を生成してHTMLをブラウザに送り返す。
  • 動的なサイトでは、コントローラは (ユーザーなどの) サイトの要素を表しており、データベースとの通信を担当しているモデル (model) と対話する。
  • モデルを呼び出した後、コントローラはビューを描画して完成したWebページをHTMLとしてブラウザに返す。

railsのmvc

チュートリアル 1.3.3 Model-View-Controller (MVC)

1.3.4 Hello, world!

hello, world! という文字を表示するためのコントローラアクションを追加する。

現在あるコントローラを確認できるコマンド
$ls app/controllers/*_controller.rb

application_controller.rb にhelloアクションを追記する。

def hello
  render html: "hello, world!"
end

次に、デフォルトページに Yay! の表示ではなく、helloアクションを利用する。そのために、routerファイルを編集してルーティングを変更する。

これを追記する。

root 'application#hello'

Progateだと get “/” => “home#top” のような書き方をしていたが、rootを使うのでも良いらしい。

ブラウザを更新すると、hello, world!が表示される!

演習

  1. リスト 1.7のhelloアクションを書き換え、「hello, world!」の代わりに「hola, mundo!」と表示されるようにしてみましょう。
    ▶helloアクションの中身を書き換えるだけ。
  2. Railsでは「非ASCII文字」もサポートされています。「¡Hola, mundo!」にはスペイン語特有の逆さ感嘆符「¡」が含まれています (図 1.16)18。「¡」文字をMacで表示するには、Optionキーを押しながら1キーを押します。この文字をコピーして自分のエディタに貼り付ける方が早いかもしれません。
    ▶同様にhelloアクションの中身を書き換えると、¡ も表示できた。
  3. リスト 1.7のhelloアクションを参考にして、2つ目のアクションgoodbyeを追加しましょう。このアクションは、「goodbye, world!」というテキストを表示します。リスト 1.9のルーティングを編集して、ルートルーティングの割り当て先をhelloアクションからgoodbyeアクションに変更します (図 1.17)。
    アクションを作って
    def goodbye
    render html: "goodbye, world!"
    end
    ルーティングを変更した
    root 'application#goodbye'

1.4 Gitによるバージョン管理

コードの履歴を追ったり、削除してしまったときの復旧(ロールバック)のために、バージョン管理が必要。

Gitについて知るのは「Pro Git book」がおすすめ。

1.4.1 インストールとセットアップ

Cloud9にはすでにGitが導入されている。次のコマンドで最初の設定をする。

名前とメールアドレスを各自のものに変更する。これはリポジトリ上で一般公開される点に注意。

$ git config --global user.name "Your Name"
$ git config --global user.email your.email@example.com

次にリポジトリの初期化を行う。そのために、アプリケーションのルートディレクトリに移動する。

hello_appだったら、cd ~/enviroment/hello_app で移動しておく。

$ git init

そして、プロジェクトファイルをリポジトリに追加する。

$ git add -A

これは、現在のディレクトリにあるファイルがすべて追加されるコマンド(.gitignore に記載のファイルは無視される)。

これでステージング (Staging) という待機用リポジトリに置かれる。ステージング状態などのGitの状態は次のコマンドで確認する。

$ git status

リポジトリに反映するために、コミット(commit)する。

$ git commit -m "Initialize repository"

-m で、コミットメッセージを”Initialize repository”と指定している。メッセージの履歴は次のコマンドで確認できる。

$ git log

1.4.2 Gitのメリット

次のコマンドでファイルを削除してしまった場合・・・

$ rm -rf app/controllers/
$ ls app/controllers/
ls: app/controllers/: No such file or directory

これではまだ削除した状態はコミット(保存)されていないので、checkoutすると元に戻せる。

$ git checkout -f
$ git status
# On branch master
nothing to commit (working directory clean)
$ ls app/controllers/
application_controller.rb  concerns/

1.4.3 Bitbucket

Bitbucketは、Gitリポジトリのホスティングと共有に特化したサイト。

  • GitHub リポジトリを一般公開する場合は無料、公開しない場合は有料
    (GitHubも2019年1月より無料で非公開設定できます 参考のQiita記事
  • Bitbucket 共同作業者が一定数以下ならリポジトリを公開しなくても無料、共同作業者が一定数を超えると有料

その他、GitLabという同系統のサービスもある。

Bitbucket を使うためにGitのSSH公開鍵が必要なので、Cloud9のターミナルで次のコマンドを打ってみる。

ec2-user:~/environment $ cd ~/.ssh
ec2-user:~/.ssh $ ls
authorized_keys

id_dsa.pub というファイルがないので、生成する。パスフレーズなどを求められるが、不要なら空のままEnterで良い。参考:Git サーバー – SSH 公開鍵の作成

ec2-user:~/.ssh $ ssh-keygen
ec2-user:~/.ssh $ cat ~/.ssh/id_rsa.pub

cat コマンドで中身が確認できたら、SSH 公開鍵をコピーしてBitbucketの設定で貼り付けます。

bitbucket ssh鍵の設定

README をNoにしてリポジトリを作成したら、表示される画面を参考にアプリケーションが置いてあるフォルダに移動してからコマンドを入力します。

$ git remote add origin git@bitbucket.org:ユーザー名/リポジトリ名.git
$ git push -u origin master

2つ目のコマンドでパスワードを求められるので、bitbucketにログインするパスワードを入力します。

これでリポジトリにファイルが追加されました。

1.4.4 ブランチ、編集、コミット、マージ

先ほどのコマンドでプロジェクトの内容を表すREADMEファイルがリポジトリに追加されているので、その内容を書き換えてみる。

Branch (ブランチ)
Branch (ブランチ)とは、親リポジトリであるmasterブランチからのコピーのこと。実験のためにコード変更を試したい場合などに利用する。

$ git checkout -b modify-README
$ git branch
  master
* modify-README

ここでは、短期間だけ使うトピックブランチをcheckoutと-bフラグで作成している。またmodify-README ブランチを指している状態です。

Edit (編集)
Cloud9 にあるREADMEファイルを開いて編集します(テキトーに追記などする)。

Commit (コミット)
ファイルの変更を終えたときのブランチの状態を見てみると、READMEが修正(modified)されているのが分かります。

$ git status
・・・
modified:   README.md
・・・

メッセージを付けてコミットします。

$ git commit -a -m "Improve the README file"

Merge (マージ)
masterブランチに変更をマージ (merge) します。

$ git checkout master
$ git merge modify-README

masterブランチの内容に切り替えて、modify-READMEブランチの変更内容を反映しました。

変更が終わったので、modify-READMEブランチを削除します(削除せずにそのままでも問題ない)。

$ git branch -d modify-README

Push (プッシュ)
Bitbucketに変更をプッシュします。

$ git push

一度 $ git push -u origin master のコマンドを入力しているので、origin masterは省略できる。Bitbucketに行くと変更されているのが確認できます。

1.5 デプロイする

頻繁に本番環境にデプロイすると、問題に気付きやすいというメリットがある。

デプロイ環境を提供しているサービスherokuを使います。herokuにはRuby開発者のまつもとゆきひろ氏を含む4名のコアメンバーが社員としているようですよ。

1.5.1 Herokuのセットアップ

HerokuではPostgreSQLデータベースが使われている(ポストグレスキューエルと読むらしい)。

PostgreSQLと通信するために pg というgemを入れます。

# Gemfileに追記する
group :production do
  gem 'pg', '0.20.0'
end

HerokuではSQLiteがサポートされていないので、sqlite3というgemが本番環境に入らないようにする。

group :development, :test do
  gem 'sqlite3', '1.3.13'
  gem 'byebug',  '9.0.6', platform: :mri
end

チュートリアルに従ってここまでくると、sqlite3 はすでにこのような状態だったので何もしなくて良さそうだった。

本番用以外のgemをインストールしてGemfile.lockに反映させたあと、コミットする。

$ bundle install --without production
$ git commit -a -m "Update Gemfile for Heroku"

次にherokuにユーザー登録して、そのあと次のコマンドでHerokuコマンドラインクライアントがインストールされているか確認します。

$ heroku --version

ない場合はインストールしておきます。インストールコマンドは、cloud9などのクラウドIDEの場合。

$ source <(curl -sL https://cdn.learnenough.com/heroku_install)

コマンドを入力してherokuへログインします。

$ heroku login --interactive
$ heroku keys:add

herokuサーバーにアプリケーションの実行場所を作成します。

$ heroku create

Railsアプリケーション専用のサブドメインが作成された状態となりました。

1.5.2 Herokuにデプロイする (1)

Gitを使って、herokuにリポジトリをプッシュする。

$ git push heroku master

いくつか警告が出ますが、ここでは無視しておいて良いようです。

1.5.3 Herokuにデプロイする (2)

表示されたURLにアクセスすると、アプリケーションが表示されます。ローカル環境の場合は heroku open でも開くことができる。

私の場合はうまく開かなかったので rails server で見てみようとすると、Gem::GemNotFoundException というエラーが出たが、bundlerを入れ直すとうまくいった。再度herokuにプッシュしてもherekuでは開けない。

$ cd ~/enviroment/hello_app
$ rails server
$ gem install bundler
$ bundle install

$ heroku run rails console で状況を見てみると、sqlite3がないというようなことを言われている。

Specified 'sqlite3' for database adapter, but the gem is not loaded. Add `gem 'sqlite3'` to your Gemfile (and ensure its version is at the minimum required by ActiveRecord). (Gem::LoadError)

先ほど $ bundle install –without production した辺りで、HerokuではSQLiteがサポートされていないことを書いた。

よって、heroku側にPostgreSQLを導入する必要があるようだ。参考

$ heroku addons:create heroku-postgresql:hobby-dev
$ heroku run rake db:migrate

これで表示された。

演習

  1. 1.3.4.1と同じ変更を行い、本番アプリでも「hola, mundo!」を表示できるようにしてください。
    ▶すでにコントローラの中にアクションは作成されているので、ルーティングを変更した。
    root ‘application#hello’
    コミットして $ git commit -a -m “enshu1.5.3-1”
    プッシュした $ git push heroku master
  2. 1.3.4.1と同様、ルートへのルーティングを変更してgoodbyeアクションの結果が表示されるようにしてください。またデプロイ時には、Git pushのmasterをあえて省略し、git push herokuでデプロイできることを確認してみてください。
    ▶ルーティングを変更 root ‘application#goodbye’
    コミットして $ git commit -a -m “enshu1.5.3-2”
    プッシュした $ git push heroku

1.5.4 Herokuコマンド

アプリケーション名を変更する。

$ heroku rename example

https://example.herokuapp.com/ のように好きなアドレスに変えられる。他と被ったら変更できない。

Rubyでは (‘a’..’z’).to_a.shuffle[0..7].join という記述でランダムな文字列を生成できるので、秘密のURLを作るのもあり。また、herokuは独自ドメインを設定することもできる。

Ruby on Railsチュートリアル自体がherokuで動いているらしい。

演習

  1. heroku helpコマンドを実行し、Herokuコマンドの一覧を表示してみてください。Herokuアプリのログを表示するコマンドはどれですか?
    ▶$ heroku logs だと思う。
  2. 上の演習で見つけたコマンドを使って、Herokuアプリの最近のログ (log) を調べてみましょう。直近に発生したイベントは何でしたか? (このログを調べるコマンドを覚えておくと、本番環境の不具合を見つけるときに役立ちます)
    ▶Couldn’t find that app. そんなアプリは見つからない?ログがないということかな

1.6 最後に

この章ではインストール、開発環境の設定、バージョン管理、本番環境へのデプロイなどの課題に取り組んだ。

次の章では、データベースを備えたtoyアプリをつくり、Railsの詳しい動作を見ていく。

Twitterでチュートリアル関連の発信をする場合は「#Railsチュートリアル」を付けると良いそうだ。