Rails Tutorialを咀嚼する【第2章 Toyアプリケーション】


2.1 アプリケーションの計画

■rails generate
以下4つの使い方がある。
1.rails generate controller
→コントローラーとビューとルーティングを生成
2.rails generate model
→モデルとマイグレーションファイルを生成
3.rails generate migration
→マイグレーションファイルを生成
4.rails generate scaffold
→全て(コントローラー、ビュー、モデル、マイグレーションファイル、ルーティング)を生成。

以下の説明が分かりやすい
https://diveintocode.jp/blogs/Technology/RailsGenerateCommand

■マイグレーション
マイグレーションファイルを元にDBのテーブル操作を行う仕組み。
直接SQL文を書かずにDBをいじれる。(テーブルの作成ができる)

■マイグレーションファイル
DBを生成する際の設計図。スクリプトファイル。
rails db:migrate を実行することでDBに反映される。

2.2 Usersリソース

■rails generate scaffold User name:string email:string
データベース上にusersというテーブルをする。
そのテーブルにはidとnameとemailがある。
という意味。
これによりusers_controller.rbが生成される。

■resources :users
usersに対応する
index
create
new
edit
show
update
destroy
が全て作成される。「:」はシンボル。

■シンボル
Rubyが早くなるおまじない。

【演習】
1,2,3,4全部やってみるだけ。

@users = User.all
@から始まる変数をインスタンス変数と呼ぶ。
コントローラー内で宣言する。
宣言するとビューでも使えるようになる。

【演習】
1.図にするのは面倒なのでパス。
2.図示した振る舞いを見ながら、Scaffoldで生成されたコードの中でデータベースからユーザー情報を取得しているコードを探してみてください。
→データベースに関連するのはモデル。しかし今回作成されたモデル
・application_record.rb
・user.rb
には該当するコードなし。
すると、コントローラー側でモデルに関わっている個所を探す。
@user=~と書いてある場所はそんなに多くない。

user_controller.rb
  private
    # Use callbacks to share common setup or constraints between actions.
    def set_user
      @user = User.find(params[:id])
    end

set_userというメソッドを作成。
User.findでユーザーを探している。
find()はモデルを検索するメソッド。
paramsもメソッド。
params[:カラム名]で内容を呼び出せる。
ここではモデルの中にあるidを呼び出している。

3.ユーザーの情報を編集するページのファイル名は何でしょうか?
編集ページを探すので組み込みrubyの「edit.html.erb」が正解。

2.3 Micropostsリソース

■rails generate scaffold Micropost content:text user_id:integer
idとcontentとuser_idを持つマイグレーションファイルを生成する。

■resources :microposts
micropostsに対応する
index
create
new
edit
show
update
destroy
が全て作成される。「:」はシンボル。
これによりmicroposts_controller.rbが生成される。

【演習】
1,2,3,4どれも試してみてください。

■validates :content, length: { maximum: 140 }
contentの中身の長さが140文字を超えたらエラーを表示させるというバリデーション。

■validatesメソッド
validate A,B でAがBでなければエラーを表示させる的なニュアンス。

【演習】
省略

■has_many :microposts
1人のユーザーに複数のマイクロポストがある。
データベースに関与するためmodelに記載する。
ユーザーに関する属性なのでuser.rbに記載する。

■belongs_to :user
1つのマイクロポストは1人のユーザーにのみ属する。
データベースに関連するものなのでmodelに記載する。
投稿に関するものなのでmicropost.rbに記載する。

【演習】
1.ユーザーのshowページを編集し、ユーザーの最初のマイクロポストを表示してみましょう。同ファイル内の他のコードから文法を推測してみてください (コラム 1.1で紹介した技術の出番です)。うまく表示できたかどうか、/users/1 にアクセスして確認してみましょう。

「showページ」「表示」とあるので、MVCでいえばビュー。ビューフォルダを探すとshow.html.erbがあるので中を見ましょう。
名前とメールが表示される記載があるので、まねて書くとこうですね。

show.html.erb
<p id="notice"><%= notice %></p>

<p>
  <strong>Name:</strong>
  <%= @user.name %>
</p>

<p>
  <strong>Email:</strong>
  <%= @user.email %>
</p>

<p>
  <strong>Content(中身):</strong>
  <%= @user.microposts.first.content %>
</p>

<%= link_to 'Edit', edit_user_path(@user) %> |
<%= link_to 'Back', users_path %>

@userはインスタンス変数。user_controller.rbで宣言している。
ここでは@user = User.find(params[:id])を指定してる。
micropostsで投稿内容、firstで一番最初の投稿を呼び出す。
.contentは不明。おまじない?

2.リスト 2.16は、マイクロポストのContentが存在しているかどうかを検証するバリデーションです。マイクロポストが空でないことを検証できているかどうか、実際に試してみましょう (図 2.16のようになっていると成功です)。
その通り記載してみてください。

3.リスト 2.17のFILL_INとなっている箇所を書き換えて、Userモデルのnameとemailが存在していることを検証してみてください (図 2.17)。
→そのまんまの問題。

show.html.erb
class User < ApplicationRecord
  has_many :microposts
  validates name, presence: true    # 「FILL_IN」をコードに置き換えてください
  validates email, presence: true    # 「FILL_IN」をコードに置き換えてください
end

■継承
モデルはApplicationRecordを継承している。
コントローラーはApplicationControllerを継承している。

■ApplicationRecord、ApplicationController
既にいろいろなものが定義されているパッケージみたいなもの。
何が定義されているのかは不明。
今はおまじないのようなものだと解釈。

【演習】
1.Applicationコントローラのファイルを開き、ApplicationControllerがActionController::Baseを継承している部分のコードを探してみてください。
→1行目のコード。

2.ApplicationRecordがActiveRecord::Baseを継承しているコードはどこにあるでしょうか? 先ほどの演習を参考に、探してみてください。ヒント: コントローラと本質的には同じ仕組みなので、app/modelsディレクトリ内にあるファイルを調べてみると...?)
→application_record.rbってファイルがありますね。言われるまで意識したことなかった。
ここの一番上のコードです。

残りはさらっと流してください。