面接で技術質問されたので、復習しました

#はじめに
昨日もある企業と面接をさせていただきました。そこでされた質問について、今回も改めて冷静な状態で答えるとしたらどうするかを考えていきます。
前回の面接での技術的な質問の振り返りはこちらです↓
[面接で出題されたコーディングテストを冷静になって考えてみた](https://qiita.com/TerToEer_sho/items/62800cbdc9a3b1f04788)
[面接での技術質問の反省①](https://qiita.com/TerToEer_sho/items/92de60d90e5496d0b2e1)
[面接での技術質問の反省②](https://qiita.com/TerToEer_sho/items/1fe9a33b37d4279d35cf)

記事に出てくるコードは切り取ったものなので、ご容赦ください。また、読みにくいコードや言葉使いが多々あると思います。
##質問に至るまで
今回の面接官の方も、私のオリジナルアプリを見ていただき、その機能についていくつか質問をされました。
##「送信」が押されたときのフロントの動きを説明して
###意図
ちゃんと意図を汲み取ることができなかったことが悔やまれます。冷静な今、考えるに、Railsを使っているので、「ちゃんとMCSについて理解できているのか」ということを確認したかったのではないかと想像します。あくまで想像なので、本当はもっと深いところまで理解しているか問いたかったのかもしれませんが…それは置いておきます。

###MVC
MVCはモデル、ビュー、コントローラーの頭文字を取ったものです。今回は、「送信」が押されたときのフロントの動きなので、結構全体的に説明が必要になりそうです。

###ざっくりとした流れ
1.　送信ボタンを押す。
2.　そのボタンに設定されているurlをルーティングに飛ばす。
3.　urlと一致するコントローラーのアクションを呼び出す。
4.　アクションの処理を行う。
5.　処理の中でモデルにurlを一緒に飛んできたパラメーターをデータベースに渡し、保存する。
6.　送られているメッセージを表示させるためのアクションが実行される。
7.　表示させるアクション内でデータベースから、メッセージを取ってくる。
8.　そのメッセージを変数に入れる。
9.　ビューでメッセージの入った変数を繰り返し処理を用いて、表示させる。

###viewの記述
form_withでは、urlかmodelの指定が必要です。今回は、modelを指定しているので、Rails側で勝手にurlを推測してくれます。テーブルにすでに存在するものであれば、更新と判断、新規であれば、新規作成と判断してくれます。

```erb:view
<div class="message-display">
  <%= render partial: 'message', collection: @messages %>
</div>
<div class="message-box">
  <%= form_with model: [@class_room, @message], local: true do |f| %>
    <%= f.text_field :content, class:"content", placeholder:"メッセージ(300文字まで)", min:1, max: 300 %>
    <div class="image">
      <%= f.label :image, class:"fas fa-image" %>
      <%= f.file_field :image, style: "display: none;"%>
    </div>
    <%= f.submit "送信する", class:"message-send" %>  
 <% end %>
</div>
```
###ルーティング

```rb:routes
resources :class_rooms, only: [:index, :new, :create, :show]
```

`resources`でまとめてしまっているが、今回はcreateアクション。
ターミナルでルーティングを確認すると、

```bash:rails_routes
class_room_messages POST /class_rooms/:class_room_id/messages(.:format) messages#create
```
`class_room_messages`というurlでHTTPがPOSTのときは、messages.controllerのcreateアクションを行う。

###コントローラー
「送信」ボタンが押されたときに、行うアクションは`create`

```rb:controller
def index
  @message = Message.new
  @messages = @class_room.messages.includes(:user)
end
def create
  @message = Message.new(massage_params)
  if @message.save
    redirect_to class_room_messages_path(current_user.class_room.id)
  else
    @messages = @class_room.messages.includes(:user)
    render :index
  end
end
private
  def massage_params
    params.require(:message).permit(:content, :image).merge(user_id: current_user.id, class_room_id: params[:class_room_id])
  end
```
ストロングパラメーターで規制しているため、データベースのmessageテーブルに渡すことができるのは、、`:content, :image, :current_user.id, :class_room_id`のみです。
もし保存できたら、`class_room_messages_path`を飛ばす。（ルーティングで処理をする先を判断）

保存ができて、`class_room_messages_path`を飛ばしたら、同じコントローラーの`index`の処理を行うことになります。
indexの`@messages`という変数がビューに渡されます。
別のファイルにある繰り返し処理で表示させる内容は`_message.html.erb`に記述してあります。

```erb:view
<%= render partial: 'message', collection: @messages %>
```

###モデル
保存できるかデータベースとやりとりを行う。
バリデーションによって、必要なデータはあるのか、データの型にちゃんと合っているかを判断します。

```rb:model
validates :content, presence: true, unless: :was_attached?

def was_attached?
  self.image.attached?
end
```

##最後に
今回も現役のエンジニアの方にアプリを見ていただけたのは、恥ずかしいけど嬉しかったです。面接を経験していくことで少しずつ知識も獲得していきたい。
説明をするときの正しい言葉使いがわからない…urlは飛ばすものなのか？変数を渡すという言い方であっているのか？
こういった内容を話す経験が無さすぎて、「現場でその言い方しても伝わらないよ」と言われたらそれまでです。いろんな記事を読んで真似しているつもりではあるけれど…

エディタ使って指し示しながらなら出来るけど、言葉だけってのは難しいな…。この記事を通して復習ができました。