owned this note
owned this note
Published
Linked with GitHub
<h1>Railsチュートリアル 第2回報告</h1>
<h2>Toyアプリケーションを作る!</h2>
第2章では、Railsの持つ機能を実際に使用してみるためのアプリケーション制作に挑戦する。大量の機能を自動的に生成するscaffold(=足場)ジェネレータというスクリプトを使用したWebアプリケーション作成を通して、RailsプログラミングとWebプログラミングの概要を学習する。
<h3>まずは基礎作り</h3>
最初に、アプリケーションのひな型を作成することが出来る<font color="red">rails new</font>コマンドでアプリケーションの基礎を作成する。
```
$ cd ~/environment
$ rails _5.1.6_ new toy_app
$ cd toy_app/
```
その後、rails newコマンドで自動的に作成された<font color="red">Gemfile</font>というファイルを今回使用するに適した形に編集する。
```
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.7.0'
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
group :production do
gem 'pg', '0.20.0'
end
# Windows環境ではtzinfo-dataというgemを含める必要があります
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
```
その後、<font color="red">bundle update→bundle install</font>で今回のために必要なgemをインストール。前章でも解説があったように、<font color="red">--without production</font>オプションで開発環境用のローカルgemのみをダウンロード可能。
```
$ bundle update
$ bundle install --without production
```
その後、Gitでこのアプリケーションを管理できるようにするため、コマンドで初期化、追加、コミットを行う。
```
$ git init //現在のディレクトリをgit管理対象に
$ git add -A //ファイルをステージングエリアに追加
$ git commit -m "Initialize repository" //リポジトリに追加
```
続いて、Bitbucket(ウェブベースのGitバージョン管理サービス)のサイト上でリポジトリを作成し、ファイルをプッシュ。
```
$ git remote add origin git@bitbucket.org:<username>/toy_app.git
$ git push -u origin --all
```
最後に、Herokuにプッシュを行い、下準備を整える。
> **Applicationコントローラにhelloアクションを追加する**
app/controllers/application_controller.rb
```
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
def hello
render html: "hello, world!"
end
end
```
> **ルートルーティングを設定する**
config/routes.rb
```
Rails.application.routes.draw do
root 'application#hello'
end
```
上記2つの変更をHerokuにプッシュして、下準備が完了する。
```
$ git commit -am "Add hello"
$ heroku create
$ git push heroku master
```
<h3>Usersリソースの生成</h3>
<font color="red">Usersリソース</font>とは、ユーザー用のデータモデルとモデル表示用のWebインタフェースをひとまとめにした総称。リソース生成には<font color="red">scaffoldジェネレータ</font>が必要。<font color="red">rails generate</font>スクリプトに<font color="red">scaffold</font>コマンドを渡すことで生成。
```
$ rails generate scaffold User name:string email:string
invoke active_record
create db/migrate/20160515001017_create_users.rb
create app/models/user.rb
invoke test_unit
create test/models/user_test.rb
create test/fixtures/users.yml
invoke resource_route
route resources :users
invoke scaffold_controller
create app/controllers/users_controller.rb
invoke erb
create app/views/users
create app/views/users/index.html.erb
create app/views/users/edit.html.erb
create app/views/users/show.html.erb
create app/views/users/new.html.erb
create app/views/users/_form.html.erb
invoke test_unit
create test/controllers/users_controller_test.rb
invoke helper
create app/helpers/users_helper.rb
invoke test_unit
invoke jbuilder
create app/views/users/index.json.jbuilder
create app/views/users/show.json.jbuilder
invoke assets
invoke coffee
create app/assets/javascripts/users.coffee
invoke scss
create app/assets/stylesheets/users.scss
invoke scss
create app/assets/stylesheets/scaffolds.scss
```
<font color="red">rails db:migrate</font>というコマンドで、データベースを更新する<font color="red">マイグレーション</font>という作業を行う。
> **データベースのマイグレート**
```
$ rails db:migrate
== CreateUsers: migrating =================================
-- create_table(:users)
-> 0.0017s
== CreateUsers: migrated (0.0018s) ========================
```
<h3>ユーザーページ</h3>
| URL |アクション| 要素 |
| -------- | -------- | -------- |
|/users| index| 全ユーザーの一覧を表示|
|/users/1|show|id=1のユーザーを表示|
|/users/new|new|新規ユーザーを作成|
|/users/1/edit|edit|id=1のユーザー情報を編集|
新規ユーザーを作成するたびidが1ずつ加算される。
<h3>演習(1)</h3>
1. CSSを知っている読者へ: 新しいユーザーを作成し、ブラウザのHTMLインスペクター機能を使って「User was successfully created.」の箇所を調べてみてください。ブラウザをリロードすると、その箇所はどうなるでしょうか?
A. 「User was successfully created.」の部分が消える
2. emailを入力せず、名前だけを入力しようとした場合、どうなるでしょうか?
「@example.com」のような間違ったメールアドレスを入力して更新しようとした場合、どうなるでしょうか?
A. emailの欄は空欄のままユーザー登録され、間違ったメールアドレスもそのまま登録される
3. 上記の演習で作成したユーザーを削除してみてください。ユーザーを削除したとき、Railsはどんなメッセージを表示するでしょうか?
A. 「User was successfully destroyed.」と表示
<h3>MVCの挙動</h3>
M:Model (システム内のビジネスロジックを担当)
V:View (表示や入出力の処理)
C:Controller (ユーザの入力に基づき、ModelとViewの制御)
**MVCの流れ(例:「/user」リクエスト)**
1. ブラウザからURLリクエスト「/users」をRailsサーバーに送信
2. 「/users」リクエストはRailsのルーティングに到達し、そこで適切なコントローラのアクションに割り当てられる
> **URLをUserソースでのコントローラのアクションに割り当て・ルーティングの追加**
config/routes.rb
```
Rails.application.routes.draw do
resources :users
root 'users#index'
end
```
3. indexアクションを実行。Userモデルに「全てのユーザを取り出せ」(User.all)と問い合わせる
4. Userモデルは問い合わせを受け、全ユーザーをデータベースから取り出す
5. データベースから取り出したユーザーの一覧をUserモデルからコントローラに返す
6. Userコントローラがユーザーの一覧を@users変数に保存。indexビューに渡す
> **indexアクションの内容**
> app/controllers/users_controller.rb
```
class UsersController < ApplicationController
def index
@users = User.all
end
end
```
indexアクションでUser.allが全ユーザーの情報を取り出し、それを変数@userに代入している。
7. indexビューが起動し、ERB(Embedded RuBy:ビューのHTMLに埋め込まれているRubyコード)を実行し、HTMLを生成する
8. コントローラがビューからのHTMLを受け取り、ブラウザに返すkとでブラウザ上に表示される。
| HTTPリクエスト |URL| アクション |用途|
| -------- | -------- | -------- |-----|
|GET|/users| index|全ユーザーの一覧を表示|
|GET|/users/1|show|id=1のユーザーを表示する|
|GET|/users/new|new|新規ユーザーの作成|
|POST|/users|create|ユーザーの作成|
|GET|/users/1/edit|edit|id=1のユーザーを編集|
|PATCH|/users/1|update|id=1のユーザーを更新|
|DELETE|/users/1|destroy|id=1のユーザーを削除|
<h3>演習(2)</h3>
1. 図 2.11を参考にしながら、/users/1/edit というURLにアクセスしたときの振る舞いについて図を書いてみてください。
A.
2. 図示した振る舞いを見ながら、Scaffoldで生成されたコードの中でデータベースからユーザー情報を取得しているコードを探してみてください。
A. @Users
3. ユーザーの情報を編集するページのファイル名は何でしょうか?
A. edit
<h3>マイクロポストについて</h3>
マイクロポストとは、短文のテキスト(Twitterのつぶやき?)のようなものである。
Usersリソースと同様にMicropostsリソースもscaffoldでコードを生成する。
```
$ rails generate scaffold Micropost content:text user_id:integer
invoke active_record
create db/migrate/20160515211229_create_microposts.rb
create app/models/micropost.rb
invoke test_unit
create test/models/micropost_test.rb
create test/fixtures/microposts.yml
invoke resource_route
route resources :microposts
invoke scaffold_controller
create app/controllers/microposts_controller.rb
invoke erb
create app/views/microposts
create app/views/microposts/index.html.erb
create app/views/microposts/edit.html.erb
create app/views/microposts/show.html.erb
create app/views/microposts/new.html.erb
create app/views/microposts/_form.html.erb
invoke test_unit
create test/controllers/microposts_controller_test.rb
invoke helper
create app/helpers/microposts_helper.rb
invoke test_unit
invoke jbuilder
create app/views/microposts/index.json.jbuilder
create app/views/microposts/show.json.jbuilder
invoke assets
invoke coffee
create app/assets/javascripts/microposts.coffee
invoke scss
create app/assets/stylesheets/microposts.scss
invoke scss
identical app/assets/stylesheets/scaffolds.scss
```
| HTTPリクエスト |URL| アクション |用途|
| -------- | -------- | -------- |-----|
|GET|/microposts| index|全マイクロポストの一覧を表示|
|GET|/microposts/1|show|id=1のマイクロポストを表示する|
|GET|/microposts/new|new|新規マイクロポストの作成|
|POST|/microposts|create|マイクロポストの作成|
|GET|/microposts/1/edit|edit|id=1のマイクロポストを編集|
|PATCH|/microposts/1|update|id=1のマイクロポストを更新|
|DELETE|/microposts/1|destroy|id=1のマイクロポストを削除|
<h3>演習(3)</h3>
1. CSSを知っている読者へ: 新しいマイクロポストを作成し、ブラウザのHTMLインスペクター機能を使って「Micropost was successfully created.」の箇所を調べてみてください。ブラウザをリロードすると、その箇所はどうなるでしょうか?
A. 「User was successfully created.」の部分が消える
2. マイクロポストの作成画面で、ContentもUserも空にして作成しようとするどうなるでしょうか?
A. ContentとUserの欄が空のまま作成される
3. 141文字以上の文字列をContentに入力した状態で、マイクロポストを作成しようとするとどうなるでしょうか? (ヒント: WikipediaのRubyの記事にある1段落目がちょうど150文字程度ですが、どうなりますか?)
A. 作成できる
4. 上記の演習で作成したマイクロポストを削除してみましょう。
A. 正常に削除できた
<h3>マイクロポストに字数制限を設ける</h3>
> **マイクロポストの最大文字数を140文字に制限**
>app/models/micropost.rb
```
class Micropost < ApplicationRecord
validates :content, length: { maximum: 140 }
end
```
文字数制限を設ける時、Railsでは<font color="red">validation</font>を用いる。
<h3>演習(4)</h3>
1. 先ほど2.3.1.1の演習でやったように、もう一度Contentに141文字以上を入力してみましょう。どのように振る舞いが変わったでしょうか?
A. 「1 error prohibited this micropost from being saved:」というエラーメッセージが出力された
2. CSSを知っている読者へ: ブラウザのHTMLインスペクター機能を使って、表示されたエラーメッセージを調べてみてください。
A. \<h2>1 error prohibited this micropost from being saved:\</h2>
<h3>1人のユーザーに複数のマイクロポストを関連付ける</h3>
> **1人のユーザーに複数のマイクロポストを紐づける**
> app/models/user.rb
```
class User < ApplicationRecord
has_many :microposts
end
```
> **1つのマイクロポストは1人のユーザーにのみ属する**
> app/models/micropost.rb
```
class Micropost < ApplicationRecord
belongs_to :user
validates :content, length: { maximum: 140 }
end
```
これにより、1人が複数のマイクロポストを持つことが出来る環境が出来上がる。
<h4>rails console</h4>
rails consoleとは、Railsの環境を読み込んだ状態でRubyコードを実行できるツールのこと。メソッドの動きを確かめながらの開発や、デバッグなどに役立つ。
<h3>演習(5)</h3>
1. ユーザーのshowページを編集し、ユーザーの最初のマイクロポストを表示してみましょう。同ファイル内の他のコードから文法を推測してみてください (コラム 1.1で紹介した技術の出番です)。うまく表示できたかどうか、/users/1 にアクセスして確認してみましょう。
A. 
2. リスト 2.16は、マイクロポストのContentが存在しているかどうかを検証するバリデーションです。マイクロポストが空でないことを検証できているかどうか、実際に試してみましょう (図 2.16のようになっていると成功です)。
A. 
3. リスト 2.17のFILL_INとなっている箇所を書き換えて、Userモデルのnameとemailが存在していることを検証してみてください (図 2.17)。
A. 
<h3>継承の階層</h3>
UserモデルとMicropostモデルは<font color="red">ApplicationRecord</font>というクラスを継承している。
> Userクラスでの継承
```
class User < ApplicationRecord
end
```
<h3>演習(6)</h3>
1. Applicationコントローラのファイルを開き、ApplicationControllerがActionController::Baseを継承している部分のコードを探してみてください。
A. application_controller.rbの1行目に記述されている
2. ApplicationRecordがActiveRecord::Baseを継承しているコードはどこにあるでしょうか? 先ほどの演習を参考に、探してみてください。ヒント: コントローラと本質的には同じ仕組みなので、app/modelsディレクトリ内にあるファイルを調べてみると...?)
A. app/models内にあるapplication_record.rbの1行目に記述されていた
<h3>演習(7)</h3>
1. 本番環境で2〜3人のユーザーを作成してみましょう。
A. 実際のページを参照
2. 本番環境で最初のユーザーのマイクロポストを作ってみましょう。
A. 実際のページを参照
3. マイクロポストのContentに141文字以上を入力した状態で、マイクロポストを作成してみましょう。リスト 2.13で加えたバリデーションが本番環境でもうまく動くかどうか、確認してみてください。
A. 正常に動作し、141文字以上のContentは作成されなかった。