【RailsでLINEを作る】ルームを作る
※ちょっとエラーが出た部分があったので一部更新(2020/10/20)
お久しぶりの更新です。
Rails の Action cable に大分時間がかかりました...難しい!
1週間かけて rails new して scaffold で実装できたので、いよいよ組み込んでいきたいと思います。
とはいっても見た目は一旦置いといて機能から。まずはチャットを行うルーム機能を作ります。
[参考にしたサイト] [Rails]ダイレクトメッセージ(DM)機能の実装
ユーザー間のチャットルーム機能を作る
まずは簡単にER図を。
Userはもちろんユーザー、TalkRoomはチャット行う部屋を表します。(もっと簡単な名前にすれば良かったと少し後悔)
中間テーブルは、RoomUserはどのユーザーがどのTalkRoomにいるかを表し、TalkはどのユーザーがどのTalkRoomでチャットを送ったかを表します。
まず、以前作った、友達追加機能(よくあるフォローフォロワー機能)で友達追加します。
友達追加すると、自身のページで友達一覧が表示されます。その友達をクリックするとトークルームを作るようにします。
見た目は置いといてこんな感じで。
まずviewのコード。
talk_rooms/index.html.slim(一部抜粋) .talk-rooms__list--friends span.select-friends-list 友だち ul - current_user.followings.each do |follower| li class="follower" id="#{follower.id}" = link_to user_path(follower.id) do = render partial: 'users/attachment', locals: { user: follower} p = follower.name
自身が追加している友達(フォローユーザー)をeachで回します。 クリックで、その友達のshowへ飛ぶようにします。
続いてコントローラー。ここは参考にしたサイトを思いっきり使わせていただきました。
users_controller.rb def show @user = User.find(params[:id]) # ここからルームの分岐 @current_room = RoomUser.where(user_id: current_user.id) @another_room = RoomUser.where(user_id: @user.id) unless @user.id == current_user.id @current_room.each do |cr| @another_room.each do |ar| # ルームが存在する時 if cr.talk_room_id == ar.talk_room_id @is_room = true @room_id = cr.talk_room_id end end end # なければ新規作成 unless @is_room @room = TalkRoom.new @room_user = RoomUser.new end end end
自身及び友達が登録されているRoomUserをeachで回し、回している最中に同じTalkRoom.idが存在すれば、それはすでにルームが作成されているのでルームが存在する処理を、なければ新規で作る処理を行います。
続いてshowページのviewです。
users/show.html.slim p = @user.name - unless @user.id == current_user.id - if @is_room == true = link_to "チャット", talk_room_path(@room_id) - else = form_with model: @room, url: talk_rooms_path, local: true do |f| = fields_for @room_user do |ru| = ru.hidden_field :user_id, value: @user.id = f.submit 'チャット'
もしも友達とのルームがあれば、TlakRoom.showへ遷移し、なければ新規で作る形になります。 新規で作る場合は、submitで talk_rooms_controllerのcreateへ飛びます。
talk_rooms_controller def create room = TalkRoom.create RoomUser.create(user_id: current_user.id, talk_room_id: room.id) RoomUser.create(user_id: params[:room_user][:user_id], talk_room_id: room.id) # 新規ルーム作成時に、showでparams[:user_id]を使えるようにする user = User.find(params[:room_user][:user_id]) redirect_to talk_room_path(room, user_id: user) end def show @user = User.find(params[:user_id]) @room = TalkRoom.find(params[:id]) @talks = @room.talk end
まず新規でTalkRoomを作ってしまいます。 新規で作られたTalkRoomに紐づいたRoomUserレコードを2つ作ります。 自身と友達の2つです。
これで同じトークルームに参加しているユーザーが判断できるようになりました。
参考した記事のほぼ丸パクリではありますが、ルーム機能を作ることができました。
いよいよActioncableでチャット機能を作っていきます。
実装がおわたらまたボチボチ更新していきます。