LoginSignup
2
1

More than 3 years have passed since last update.

【Rails】マッチングアプリのDMフォームを作成する方法

Posted at

環境

macOS 10.15.7
Rails 5.2.4.4
Docker 19.03.13

前提

●ログインユーザーと特定のユーザー同士のみがDMページへ移動してやり取りを行うことを前提
●ログインユーザーがDM中のユーザーの一覧が閲覧できるページを作成
●メニューバーからDM中のユーザーの一覧への移動が可能

特定のユーザー同士がやり取りできるDMページの作成

まずは特定のユーザー同士がやり取りできるDMページの作成をします。

モデルの作成

UseRoomテーブルを作成してカラムは以下のようにします。

terminal
rails g model UserRoom user_id:integer room_id:integer

Roomテーブルを作成します。

terminal
rails g model Room

messageテーブルを作成してカラムは以下のようにします。

terminal
rails g model Message user_id:integer room_id:integer message:string

次に以下のように関連付けさせます。

app/models/room.rb
has_many :user_rooms
has_many :messages
app/models/message.rb
belongs_to :user
belongs_to :room
app/models/user.rb
has_many :user_rooms
has_many :messages

マイグレートをします。

terminal
rails db:migrate

コントローラーの作成

terminal
rails g controller messages

コントローラーに以下のように追記します。

app/controllers/messages_controller.rb
class MessagesController < ApplicationController
  before_action :authenticate_user
  def show
    # これからDMを行うユーザーを取得する
    @user = User.find(params[:id])
    # ログイン中のユーザーのuser_roomにあるroom_idの値の配列を取得する
    rooms = @current_user.user_rooms.pluck(:room_id)
    # room_idが上記のroomsに一致するレコードを取得する
    user_rooms = UserRoom.find_by(user_id: @user.id, room_id: rooms)
    # user_roomが見つかったら@roomに代入する
    unless user_rooms.nil?
      @room = user_rooms.room
    else
      # user_roomがない場合は新しくroomを作る
      @room = Room.new
      @room.save
      # user_roomをログインしているユーザーと相手の分を作成する
      UserRoom.create([{:user_id => @current_user.id, :room_id => @room.id}, {:user_id => @user.id, :room_id => @room.id}])
    end
    # メッセージの履歴を取得
    @messages = @room.messages
    # 新規メッセージ用オブジェクトの作成
    @message = Message.new(room_id: @room.id)
    render("users/message_form")
  end
  def create
    # メッセージの作成
    # message_paramsからパラメータを取得する
    @message = @current_user.messages.new(message_params)
    @message.save
    redirect_to request.referer
  end
  private
  def message_params
    params.require(:message).permit(:message, :room_id)
  end
end

routes.rbの編集

下記のコードを追記します。

routes.rb
  get 'message/:id' => 'messages#show', as: 'message'
  resources :messages, only: [:create]

viewの作成

今回はメッセージフォームの下にユーザー同士のコメントが表示されるようになります。

message_form.html.erb


<div class="dm">
  <h1>DMを送る</h1>
  <div class="message-form">
    <%= form_with model: @message do |f| %>
      <%= f.text_area :message %>
      <!-- メッセージ作成時に必要な :room_idをおいておく -->
      <%= f.hidden_field :room_id %>
      <%= f.submit "投稿" %>
    <% end %>
  </div>
  <table>
    <thead>
        <tr>
            <td>投稿者名</td>
            <td>投稿内容</td>
        </tr>
    </thead>
    <tbody>
        <% @messages.each do |message| %>
            <tr>
                <td><%= message.user.name %></td>
                <td><%= message.message %></td>
            </tr>
        <% end %>
    </tbody>
</table>
</div>

DM中のユーザーを一覧画面で表示

次にDM中のユーザーを一覧画面で表示できるページを作成します。

viewの作成

viewを下記のようにします。

message_user.html.erb
<% @other_rooms.each do |room| %>
  <!-- やり取り相手の名前を表示 -->
  <%= link_to(room.user.name, "/users/#{room.user.id}") %> <br>
  <!-- やり取りの中で最新のメッセージを取得して、リンクとして表示する -->
  <%= link_to(Message.find_by(id: room.room.message_ids.last)&.message, "/message/#{room.user.id}") %> <br>
<% end %>

一覧に表示させるためにこちらを追記します。

posts_controller.rb
def show_last_messages
    # ログイン中のユーザーのやり取り一覧を取得する
    current_rooms = @current_user.user_rooms
    # 空の配列を作り、ここにRoomのIDだけを格納する
    my_room_ids = []
    current_rooms.each do |user_room|
      my_room_ids << user_room.room.id
    end
    # ログイン中のユーザーを相手のIDに合わせ取得しする
    @other_rooms = UserRoom.where(room_id: my_room_ids).where.not(user_id: @current_user.id)
    render("users/message_users.html.erb")
end

routes.rbの編集

こちらを追記します。

routes.rb
get "users/last_message" => "posts#show_last_messages"

一覧ページに飛ぶためのリンク作成

わたしの場合はメニューバーから飛べるようにしたかったため下記のように追記しました。

application.html.erb
<ul class="header-menus">
  <% if @current_user %>
    <li>
      <%= link_to("こんにちは#{@current_user.name}さん", "/users/#{@current_user.id}") %>
    </li>
  <!--下記のように追記-->
    <li>
      <%= link_to("DM一覧", "/users/last_message") %>
    </li>
    <li>
      <%= link_to("ログアウト", "/logout") %>
    </li>
  <% else %>
    <li>
      <%= link_to("新規登録", "/signup") %>
    </li>
    <li>
      <%= link_to("ログイン", "/login") %>
    </li>
  <% end %>

今回は一例ですがご参考までになれたら幸いです^^

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1