<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. ![](https://i.imgur.com/0skVCUK.png) 2. リスト 2.16は、マイクロポストのContentが存在しているかどうかを検証するバリデーションです。マイクロポストが空でないことを検証できているかどうか、実際に試してみましょう (図 2.16のようになっていると成功です)。 A. ![](https://i.imgur.com/NEt2zS1.png) 3. リスト 2.17のFILL_INとなっている箇所を書き換えて、Userモデルのnameとemailが存在していることを検証してみてください (図 2.17)。 A. ![](https://i.imgur.com/fZz3k4h.png) <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は作成されなかった。
{"metaMigratedAt":"2023-06-15T02:11:52.342Z","metaMigratedFrom":"Content","title":"Railsチュートリアル 第2回報告","breaks":true,"contributors":"[{\"id\":\"be22ebc6-b157-44e4-a310-abf54e48ef32\",\"add\":0,\"del\":33},{\"id\":\"9a073587-93a1-4741-b293-9b3c057fbae5\",\"add\":15111,\"del\":3882}]"}
    230 views
   Owned this note