Rails tutorial 第7版　2章　まとめ

# rails turtorial 第2章

## scaffold で簡単なデモアプリを作る

※gemファイルの更新,クラウドIDEの設定,gitレポジトリの設定は終了している前提で進めます
また、実際にコードを書く部分だけさくっと記述しています。詳しい仕組みや説明はRails Tutorialを参照してください


### 1、scafffoldでUserリソースを作成

```
   $ rails generate scaffold User name:string email:string
```

実行すると以下のデータベースが作成される

![userのデータモデル.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3451993/74c6bdc7-7655-3e97-9007-95c34e4d36f0.png)

### 2、データベースをマイグレート
```
   $ rails db:migrate
 == CreateUsers: migrating ======================================
  -- create_table(:users)
     -> 0.0027s
  == CreateUsers: migrated (0.0036s) =============================
```


users_controllerファイル内に以下のアクションが追加されます。
```
class MicropostsController < ApplicationController
  before_action :set_micropost, only: %i[ show edit update destroy ]

  # GET /microposts or /microposts.json
  def index
    @microposts = Micropost.all
  end

  # GET /microposts/1 or /microposts/1.json
  def show
  end

  # GET /microposts/new
  def new
    @micropost = Micropost.new
  end

  # GET /microposts/1/edit
  def edit
  end

  # POST /microposts or /microposts.json
  def create
    @micropost = Micropost.new(micropost_params)

    respond_to do |format|
      if @micropost.save
        format.html { redirect_to micropost_url(@micropost), notice: "Micropost was successfully created." }
        format.json { render :show, status: :created, location: @micropost }
      else
        format.html { render :new, status: :unprocessable_entity }
        format.json { render json: @micropost.errors, status: :unprocessable_entity }
      end
    end
  end
```

これで末尾にUsersページやeditページ（userの編集ページ）などのページが作成されました。
一度ルートURLに/usersを入力し、Usersページが開くのを確認しましょう。

![usersページ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3451993/91adab46-7074-cd76-cb61-017b8233e4d2.png)


その後下記画像のように何でも良いのでnameとemailに名前とemailを適当に入力して「create user」をクリックしましょう。

![New Userを作る.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3451993/5063479d-815f-a475-32e3-b5ce48da2c13.png)


これで新しいユーザーが作成されました。

![新しいユーザーを作成する.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3451993/d983bd3c-3ca8-9d25-6450-c70827b85d45.png)


ご覧のように、各種ボタンも追加されています

-  「Edit this user」　ユーザー情報を編集
-  「Back to users」　 ユーザー一覧ページに戻る
-  「destroy this user」　現在選択しているユーザーを削除する

これで新しいユーザーの編集や追加、削除などが出来るので、一通り試してみましょう。


## MVCの挙動

MVCの挙動を一通り理解したところで、config/routes.rbに以下のコードを加えます

```
Rails.application.routes.draw do
  resources :users
  root 'users#index'
end
```

これにより最初のアクセスページが/usersのページにアクセスされるようになります。
第2章で進めて行く上で必要な記述すべきコードのみを載せていますが、MVCの挙動、Railsがどんな動きをしているかは、直接Rails Tutorialを参照してください

## Micropostsリソース

Usersリソースを作ったのと同様に、Microposts（投稿）のページとアクション等を生成します

```
 rails generate scaffold Micropost content:text user_id:integer
```

```
 $ rails db:migrate
==  CreateMicroposts: migrating ===============================================
-- create_table(:microposts)
   -> 0.0023s
==  CreateMicroposts: migrated (0.0026s) ======================================
```

これにより、以下のようなデータベースが作成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3451993/1047824c-cc1c-d069-c733-9a88cbe980ae.png)

config/routesにマイクロポスト用のURIを割り当てる

```
Rails.application.routes.draw do
  resources :microposts
  resources :users
  root 'users#index'
end
```


/usersの時と同じように、/micropostsを末尾に入力することでmicropostを投稿することが出来るので、/usersの時と同じ要領でmicropostを投稿したり、編集したりしてみましょう。


## マイクロポストをマイクロにする

マイクロポストに140文字の制限を加える
「app/models/micropost.rb」に以下の文言を加える

```
class Micropost < ApplicationRecord
  validates :content, length: { maximum: 140 }
end
```

これで140字を超えるとエラーが出るか確認してみましょう。

![スクリーンショット 2023-08-30 173811.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3451993/192a114e-4541-1be4-20c5-4fc628978801.png)

Content is too longという記述があれば成功です。

## ユーザーはたくさんマイクロポストを持っている

![スクリーンショット 2023-08-30 174512.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3451993/1157d2b3-4e7a-aed9-8356-ccc835c376b5.png)
先ほど作成したusersモデルとmicropostsを紐付けます

app/models/user.rb
```
class User < ApplicationRecord
  has_many :microposts　#1人のユーザーに複数のマイクロポストがある。
end
```

app/models/micropost.rb

```
class User < ApplicationRecord
 class Micropost < ApplicationRecord
  belongs_to :user #1つのマイクロポストは1人のユーザーにのみ属する。
  validates :content, length: { maximum: 140 }
end
```

rails consoleにて以下の作業を順に行ってみてください
```
$ rails console
>> first_user = User.first
>> first_user
>> first_user.microposts
>> micropost = first_user.microposts.first
>> micropost
>> micropost.user
>> exit
```

最初のユーザーの情報や、投稿の情報などが表示されていることを確認してみましょう。

### ※ここでの演習について

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

これに関して私は躓いたのですが、いろいろ調べたりした結果、以下のようなコードを書くのが答えのようです。

app/views/users/show.html.erb
```
<p style="color: green"><%= notice %></p>

<%= render @user %>

    #ここから追加
    <strong>Microposts</strong>
    <%= @user.microposts.first.content %>
　　#ここまで

<div>
  <%= link_to "Edit this user", edit_user_path(@user) %> |
  <%= link_to "Back to users", users_path %>

  <%= button_to "Destroy this user", @user, method: :delete %>
</div>

```

これによって登録されたユーザーの最初の投稿が反映されます

![画像1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3451993/4267d547-306d-4548-be7f-556e78767f8b.png)

ただし登録したユーザーが投稿していない場合や、2つのデータベースが上手く紐付いていない場合
以下のようなエラーが表示されます。

![スクリーンショット 2023-08-31 061256.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3451993/a4338d60-0209-ac55-1c75-047843fb9d68.png)


「undifined method content for NillClasds」
コンテントを表示したいけど、@user.micropoosts.firstがない場合、以下のエラーが出ます。

例えば2人のユーザーを登録したけれど、2人目のマイクロポストを作成していない場合など
以下のエラーが出てしまいます。私の場合はshowページのみならず編集ページなどをクリックした場合でもこのようなエラーが出てしまい、なんだか気持ち悪いです。

なので、このようなエラーが出た場合は、このコードを追加しましょう


```
<p style="color: green"><%= notice %></p>

<%= render @user %>

#下記1行を追加
<% if @user.microposts.present? %>
  <p>
    <strong>Microposts</strong>
    <%= @user.microposts.first.content %>
  </p>
#endを追加
<% end %>

<div>
  <%= link_to "Edit this user", edit_user_path(@user) %> |
  <%= link_to "Back to users", users_path %>

  <%= button_to "Destroy this user", @user, method: :delete %>
</div>
```

<% if @user.microposts.present? %>

presentメソッドは、変数の値が存在するか、しないかによって後続の処理を変更したい場合に使用し、ここでは @user.microposts.first.contentが存在しない場合、falseを返します。つまり最初の投稿があれば表示し、なければ表示しないというメソッドを使用します。

<% end %>を忘れずに追加しましょう。

![スクリーンショット 2023-08-31 062557.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3451993/78f96e0b-7ea2-5e3e-e872-59a34c7babc7.png)


## ターミナル上で現在のデータベースの情報を調べる方法

```
$ rails dbconsole
SQLite version 3.40.1 2022-12-28 14:03:47
Enter ".help" for usage hints.
```

```
sqlite> .table
ar_internal_metadata  schema_migrations   
microposts            users 
```
作成したマイクロポストとユーザーのモデルが表示されます。

```
sqlite> select * from users;
13|sample|sample@gmail.com|2023-08-30 07:37:03.090880|2023-08-30 07:37:03.090880
14|sample2|sample2@gmail.com|2023-08-30 07:47:31.315615|2023-08-30 07:47:31.315615
```

select * from モデル名;
で選んだモデルの全てのデータを表示することが出来ます。SQLで使用する記述方法ですね。

私の場合は2つのユーザーの情報のIDが13,14となっています。これはなぜかというと、1,2,3とユーザを作った場合は同じようにIDも1,2,3と振られる訳ですが、例えばIDが1のユーザーを削除した場合、次に作るユーザーのIDは4となり、2,3,4という順番になる訳です。私の場合削除を繰り返し新しくつくった2人のユーザーは13番目、14番目となってしまったわけです。

たまにマイクロポストでユーザを選ぶときに「user must exist」で選べないときは、そのIDのユーザを消してしまって、今いるユーザーのID何だっけ？となる時もあるので、この方法で確認してみましょう。

まあ、ルートURLを見ればIDは分かるのですが

![スクリーンショット 2023-08-31 063147.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3451993/aca7b256-276a-1513-59a1-57d35da2d769.png)


あとは演習通り、マイクロポストのコンテンツが存在していない場合エラーが出るように以下のコードを追加して、検証してみましょう


app/models/micropost.rb
```
class Micropost < ApplicationRecord
  belongs_to :user
  validates :content, length: { maximum: 140 },
                      presence: true #空欄の時にエラーが出る
end
```


app/models/user.rb
```
class User < ApplicationRecord
  has_many :microposts
  validates :name, length: { maximum: 140 },presence: true
  validates :email, length: { maximum: 140 },presence: true
end
```

後は演習に従ってgitにプッシュし、renderで表示できるか確認してみましょう。