[Rails初心者]コロナ自粛で暇だからRailsでチャットアプリを作る　その１

#はじめに
railsの勉強がてらチャットアプリ的なものを作ってみようと思います。今回は簡単な機能だけ作ります。
マイペースですが、今回の続きも載せる予定です。

#環境
macOS
rails5.2.4

#hamlを使えるようにする
erbではなくhamlを使おうと思います。Gemfileに以下を追加し、`$bundle install`を実行してください。
`gem "haml-rails"`

その後、`$rails haml:erb2haml`を実行すると既存のerbファイルがhamlファイルに置換されます。Controllerを作る際もhamlファイルが生成されます。

#controller,modelの作成
チャット部屋がいくつかあって、その中でやり取りすることを考えているので、

- TopPagesController
- RoomsController
- MessagesController

の3つを作ります。

```コマンド
$rails g controller TopPages top
$rails g controller Rooms show
$rails g controller Messages create
```
今回のアクションはこれだけです。

モデルは、

- RoomModel
- MessageModel

の2つです。

```コマンド
$rails g model Room name:text
$rails g model Message content:text
```
nameは部屋名、contentはメッセージの内容です。

routes.rbへの追記も忘れずにします。model作成時に自動で追記されたものは削除しても大丈夫です。

```routes.rb
Rails.application.routes.draw do
  root 'top_pages#top'
  resources :rooms
  resources :messages
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
```

RoomとMessageには１対多の関係があります（メッセージはどれか一つのチャット部屋に属する）。
それぞれのModelにhas_many, belongs_toを追記します。

```room.rb
class Room < ApplicationRecord
  has_many :messages, dependent: :destroy
end
```

```message.rb
class Message < ApplicationRecord
  belongs_to :room
end
```

`$rails g migration AddRoomToMessage`でマイグレーションファイルを作成し、以下のように追記します。

```20200429111536_add_room_to_message.rb
class AddRoomToMessage < ActiveRecord::Migration[5.2]
  def change
    add_reference :messages, :room, foreign_key: true
  end
end
```

`$rails db:migrate`を実行してDBに反映させます。

ちなみにオブジェクトの関係（１対１、１対多など）は`$rails g model`の時に同時に指定することができます（そのほうが楽です）。


#controllerの中身を書く
```rooms_controller.rb
class RoomsController < ApplicationController
 def show
    @room = Room.find(params[:id])
    @messages = Message.where(room_id: @room.id) #message一覧の取得
    @message = @room.messages.build #新しいメッセージ
  end
end
```

```messages_controller.rb
class MessagesController < ApplicationController
  def create
    @room = Room.find(message_params[:room_id])
    message = @room.messages.build(message_params)
    message.save
    redirect_to @room
  end

  private

    def message_params #strong parameter
      params.require(:message).permit(:content, :room_id)
    end
end
```

これでいいのかしら・・・・・
あと、TopPagesControllerの中身は今回はいじりません。

#viewをいじる
最終的にはSlackみたいにしようと思っているので、サイドバーを作って部屋一覧をそこに放り込みます。
どのページにも部屋一覧を表示するため、ApplicationControllerをいじります。

```application_controller.rb
class ApplicationController < ActionController::Base
  before_action :get_rooms

  def get_rooms
    @rooms = Room.all
  end
end
```

これでどのページでも部屋一覧が表示されます。
次にサイドバーのパーシャルを作ります。

```_sidebar.html.haml
#sidebar
  %h2 Rooms
  #room_list
    %ul
      - @rooms.each do |room|
        %li= link_to room.name, room
```

お次は、各部屋のメッセージ一覧です。

```rooms/show.html.haml
%h1= @room.name

#messages
  - @messages.each do |message|
    %p= message.content
    %p= message.created_at

#send
  = form_with model: @message do |f|
    = f.text_area :content
    = f.hidden_field :room_id, value: @room.id
    = f.submit '送信'
```

以上、こんな感じになります（CSSなし）。
![スクリーンショット 2020-05-03 3.45.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406559/bd9d72b0-e11a-1248-4e0c-4bde83665925.png)
なんだか掲示板みたいですね・・


#まとめ
今回は最低限の機能だけ作りました。まだまだ穴だらけのアプリケーションです。

#参考記事
[ゼロから作る、簡単WebチャットUIの作り方](https://qiita.com/codomo_pro/items/ad4806c086b02a25d45d)