この記事では、テックアカデミー(Webアプリケーションコース)のメンタリング第9回目の内容について書いています。
内容としては、ダイレクトメッセージ機能についてです。
テックアカデミーのメンタリング第9回目の内容

第9回目となるメンタリングの内容は、主にダイレクトメッセージ機能の実装についてです!
ダイレクトメッセージ機能
ダイレクトメッセージ機能を作るためには、User モデル・Message モデル・Room モデルが必要だと思っていたのですが、User モデルとUser モデルの中間テーブルとして Message モデルを用意するだけで実装することができました。
具体的には、下記のような感じです。

また、Room モデルを作らなくても良い理由として routes で設定すれば、そのルートが Room 代わりとなるんですね。
次にどのようにダイレクトメッセージ機能を実装したか、順を追って書いていきます。
ダイレクトメッセージ機能を実装する手順
まず、下記を実施し、Message モデルを作成します。
rails g model Message content:text user:references receive_user:references
生成された、messages.rb
のマイグレーションファイルは、
class CreateMessages < ActiveRecord::Migration[5.0]
def change
create_table :messages do |t|
t.text :content
t.references :user, foreign_key: true
t.references :receive_user, foreign_key: { to_table: :users }
t.timestamps
end
end
end
このようになり、ここでは、foreign_key: { to_table: :users }
を追加しています。
rails db:migrate
次に model に情報を追加していきます。
models/message.rb
belongs_to :user
belongs_to :receive_user, class_name: 'User'
ここでも、class_name: 'User'
を指定しています。
models/user.rb
has_many :messages
has_many :sent_messages, through: :messages, source: :receive_user
has_many :reverses_of_message, class_name: 'Message', foreign_key: 'receive_user_id'
has_many :received_messages, through: :reverses_of_message, source: :user
config/routes
resources :users, only: [:index, :show, :new, :create] do
resources :messages, only: [:index, :create, :destroy]
member do
get :followings
get :followers
get :favorites
end
end
resources :messages, only: [index, :create, :destroy]
を追加しました。
次にコントローラを作成します。
rails g controller messages index create destroy
ここで作成された create.html.erb
ファイルと destroy.html.erb
ファイルは使わないので消しておきます。
controllers/messages_cotroller.rb
class MessagesController < ApplicationController
before_action :require_user_logged_in
def index
@user = User.find(params[:user_id])
send_ids = current_user.messages.where(receive_user_id: @user.id).pluck(:id)
receive_ids = @user.messages.where(receive_user_id: current_user.id).pluck(:id)
@messages = Message.where(id: send_ids + receive_ids).order(created_at: :desc)
@message = Message.new
end
def create
@user = User.find(params[:user_id])
@message = current_user.messages.build(message_params)
@message.receive_user_id = @user.id
if @message.save
flash[:success] = 'メッセージを送信しました。'
redirect_back(fallback_location: root_path)
else
flash[:danger] = 'メッセージを送信できませんでした。'
redirect_back(fallback_location: root_path)
end
end
def destroy
@message = Message.find(params[:id])
@message.destroy
flash[:success] = 'メッセージを削除しました。'
redirect_back(fallback_location: root_path)
end
private
def message_params
params.require(:message).permit(:content)
end
end
views/messages/index.html.erb
<h2>メッセージ一覧</h2>
<% user = User.find_by(id: @message.receive_user_id) %>
<% @messages.each do |message| %>
<div>
<div class="media-left">
<img class="media-object img-circle" src="<%= gravatar_url(message.user, { size: 50 }) %>" alt="">
</div>
<div class="media-body">
<div>
<%= link_to message.user.nickname, user_path(message.user) %> <span class="text-muted">posted at <%= message.created_at %></span>
</div>
<div>
<%= message.content %><br>
<% if current_user == message.user %>
<%= link_to "削除", user_message_path(current_user, message), method: :delete, data: { confirm: "You sure?" }, class: 'btn btn-danger btn-xs' %>
<% end %>
</div>
</div>
<hr>
</div>
<% end %>
<h2>メッセージ</h2>
<%= render 'messages/form', message: @message %>
<%= link_to "ホームへ戻る", user_path(current_user) %>
views/messages/_form.html.erb
<%= form_for message, :url => {:action => :create} do |f| %>
<%= f.text_field :content %>
<br>
<%= f.submit '送信' %>
<% end %>
これでユーザーの詳細ページにDMに飛べるボタンを作成して完成です!
テックアカデミーのメンタリング第9回目を終えて|まとめ
ここまで、テックアカデミー(Webアプリケーションコース)のメンタリング9回目の内容について書いてきました。
今回は、ダイレクトメッセージ機能についての相談が主なメンタリングの内容でした。
次回は、第10回目です!
テックアカデミーのWebアプリケーションコースを終えての記事も書いているので、よかったら見てみてください!

コメント
Everyone loves what you guys are up too. This type of clever work and reporting!
Keep up the superb works guys I’ve incorporated you guys
to my own blogroll.