目標
開発環境
ruby 2.5.7
Rails 5.2.4.3
OS: macOS Catalina
前提
※ ▶◯◯ を選択すると、説明等が出てきますので、
よくわからない場合の参考にしていただければと思います。
- deviseでログイン環境構築
- ユーザー詳細画面と一覧と作成済み
流れ
1 modelの作成
2 modelの編集
3 controllerの作成
4 routingの編集
5 viewの編集
modelの作成
ターミナル
$ rails g model Room
$ rails g model Chat user_id:integer room_id:integer message:string
$ rails g model UserRoom user_id:integer room_id:integer
$ rails db:migrate
補足1【room】
ユーザー同士が会話をする部屋。補足2【chat】
ユーザーが発言した内容を保存するテーブル。補足3【user_room】
userとroomが多対多の関係性のため、中間テーブルとしてこれを管理。modelの編集
app/models/room.rb
has_many :user_rooms
has_many :chats
補足【リレーション】
room内では多くのuser_roomがあるので、1対多。 room内では多くのchatがあるので、1対多。app/chats/room.rb
belongs_to :user
belongs_to :room
app/user_rooms/room.rb
belongs_to :user
belongs_to :room
app/models/user.rb
has_many :user_rooms
has_many :chats
補足【リレーション】
1ユーザーが多くのuser_roomを保有しているので、1対多。 1ユーザーが多くのchatを行うので、1対多。controllerの作成
ターミナル
$ rails g controller chats
app/controllers/chats_controller.rb
class ChatsController < ApplicationController
def show
@user = User.find(params[:id])
rooms = current_user.user_rooms.pluck(:room_id)
user_rooms = UserRoom.find_by(user_id: @user.id, room_id: rooms)
unless user_rooms.nil?
@room = user_rooms.room
else
@room = Room.new
@room.save
UserRoom.create(user_id: current_user.id, room_id: @room.id)
UserRoom.create(user_id: @user.id, room_id: @room.id)
end
@chats = @room.chats
@chat = Chat.new(room_id: @room.id)
end
def create
@chat = current_user.chats.new(chat_params)
@chat.save
redirect_to request.referer
end
private
def chat_params
params.require(:chat).permit(:message, :room_id)
end
end
下記コメントアウトにて、分かりづらい箇所を補足。
app/controllers/chats_controller.rb
def show
# どのユーザーとチャットするかを取得。
@user = User.find(params[:id])
# カレントユーザーのuser_roomにあるroom_idの値の配列をroomsに代入。
rooms = current_user.user_rooms.pluck(:room_id)
# user_roomモデルから
# user_idがチャット相手のidが一致するものと、
# room_idが上記roomsのどれかに一致するレコードを
# user_roomsに代入。
user_rooms = UserRoom.find_by(user_id: @user.id, room_id: rooms)
# もしuser_roomが空でないなら
unless user_rooms.nil?
# @roomに上記user_roomのroomを代入
@room = user_rooms.room
else
# それ以外は新しくroomを作り、
@room = Room.new
@room.save
# user_roomをカレントユーザー分とチャット相手分を作る
UserRoom.create(user_id: current_user.id, room_id: @room.id)
UserRoom.create(user_id: @user.id, room_id: @room.id)
end
@chats = @room.chats
@chat = Chat.new(room_id: @room.id)
end
routingの編集
config/routes.rb
get 'chat/:id' => 'chats#show', as: 'chat'
resources :chats, only: [:create]
viewの編集
app/view/users/show.html.erb
<% if current_user != @user %>
<%= link_to 'chatを始める', chat_path(@user.id)%>
<% end %>
app/view/chats/show.html.erb
<%= form_with model: @chat do |f| %>
<%= f.text_field :message %>
<%= f.hidden_field :room_id %>
<%= f.submit %>
<% end %>
<table>
<thead>
<tr>
<td>投稿者名</td>
<td>投稿内容</td>
</tr>
</thead>
<tbody>
<% @chats.each do |chat| %>
<tr>
<td><%= chat.user.name %></td>
<td><%= chat.message %></td>
</tr>
<% end %>
</tbody>
</table>
補足【f.hidden_field】
f.hidden_fieldは、表示はしていないものの、paramsとして送りたいものを送る際に活用します。参考
P.S.
twitterではQiitaにはアップしていない技術や考え方もアップしていますので、
よければフォローして頂けると嬉しいです。
詳しくはこちら https://twitter.com/japwork