テックアカデミーメンタリング9回目:ダイレクトメッセージ機能

テックアカデミー

TechAcademy [テックアカデミー]Webアプリケーションコース(8週間プラン)の第9回目となるメンタリング。今回はダイレクトメッセージ機能についての内容です。

 

前回までのメンタリング

 

【第9回】メンタリング内容

第9回目となるメンタリングの内容は、主に

  • ダイレクトメッセージ機能の実装

についてでした。

 

ダイレクトメッセージ機能

最初、ダイレクトメッセージ機能を作るためにはUserモデル、Messageモデル、Roomモデルが必要だと思っていたのですが、UserモデルとUserモデルの中間テーブルとしてMessageモデルを用意するだけで実装できました。

 

具体的には、下記のような感じです。

Messageテーブルの中のモデル

 

またRoomモデルを作らなくても良い理由としてroutesで設定すれば、そのルートがroom代わりになるんですね。

 

次にどのようにダイレクトメッセージ機能を実装したか、順を追って書いていきます。

 

ダイレクトメッセージ機能を実装する手順

まず、

$ rails g model Message content:text user:references receive_user:references

を行い、Messageモデルを作成します。

 

生成された、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回目【まとめ】

今回はダイレクトメッセージ機能についての相談が主なメンタリングの内容でした。

 

これでオリジナルサービスで実装しようとしている大体の機能を追加したので、後はCSSでレイアウトを整えたり、足りない機能を追加していきたいと思います!

 

 

次回はこちら

テックアカデミーメンタリング10回目:herokuへのデータ投入、背景画像が上手く表示されない問題
テックアカデミーWebアプリケーション8週間プランのメンタリング第10回目の内容について書いています。具体的には、herokuへのデータ投入の仕方や、デプロイ後に背景画像が上手く表示されない問題についてです。

コメント

  1. Сialis より:

    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.