【Rails】自分のアクティビティ一覧を表示する【通知機能の応用】


こんにちは!
ねこじょーかー(@nekojoker1234)と申します。

先日、ゼロから独学で勉強して、Webサービス「Lookmine」を立ち上げました。

このサービスでは、以下のような通知機能を実装しています。

この機能を応用して、自分が「いいね、コメント、フォロー」した履歴を「アクティビティ」として一覧で見る機能を作りました。

やっぱり、誰にいいねをしたとか、誰に何のコメントをしたとかは一覧で見れたほうがいいですよね。

そんなわけで、実装方法をこの記事で解説することにしました。

通知機能の実装が終わっている前提なので、まだ通知機能が出来ていない人は、「通知機能を実装する方法」から読んでくださいね。

アクティビティ一覧画面の作成

アクティビティ一覧の画面を作っていきましょう。
まずは、アクティビティコントローラーの作成からです。

$ rails g controller activities

通知一覧の画面はindexで作るので、ルーティングを追加しておきましょう。
他のメソッドは不要なので、onlyを追加しています。

config/routes.rb
  resources :activities, only: :index

indexアクションを実装します。

app/controllers/activities_controller.rb
class NotificationsController < ApplicationController
  def index
    @activities = current_user.active_notifications.page(params[:page]).per(20)
  end
end

アクティビティの一覧を表示するために新しくテーブルを作る必要はなく、通知機能で使ったテーブルをそのまま流用します。

今回は、active_notificationsで、自分が送った通知を取得します。

通知機能の実装で、以下の記述をしたのを覚えていますか?

app/models/user.rb
  has_many :active_notifications, class_name: 'Notification', foreign_key: 'visitor_id', dependent: :destroy
  has_many :passive_notifications, class_name: 'Notification', foreign_key: 'visited_id', dependent: :destroy

通知機能のときは、passive_notificationsを使って、相手に送った通知を取得していました。
今回は自分が送った通知を取得したいので、active_notificationsを使います。

次に、画面の実装です。
indexの画面を作っていきましょう。

app/views/activities/index.html.slim
.col-md-6.mx-auto
  - if @activities.exists?
    - @activities.each do |activity|
      = render 'activities/activity', activity: activity
  - else
    p.text-center
      | アクティビティはありません

自分が送った通知の分だけ、部分テンプレート_activity.html.slimを呼び出しています。

app/views/activities/_activities.html.slim
- visitor = activity.visitor
- visited = activity.visited
.form-inline
  span      
    - case activity.action
    - when 'follow' then
      = link_to user_path(visited) do
        = image_tag avatar_url(visited).to_s, class: "icon_mini" 
        strong
          = visited.name
      = "さんをフォローしました"
    - when 'like' then
      span
        = link_to post_path(activity.post) do
          = image_tag avatar_url(activity.post.user).to_s, class: "icon_mini" 
          strong
            = activity.post.user.name + 'さんの投稿'
      = "にいいねしました"
    - when 'comment' then
      - if activity.post.user_id == visitor.id
        = link_to "あなたの投稿", activity.post, style: "font-weight: bold;"
      - else
        span
          = link_to post_path(activity.post) do
            = image_tag avatar_url(activity.post.user).to_s, class: "icon_mini" 
            strong
              = activity.post.user.name + 'さんの投稿'
      = "にコメントしました"
      p.text-muted.mb-0
        = Comment.find_by(id: activity.comment_id)&.comment

.small.text-muted.text-right
  = time_ago_in_words(activity.created_at).upcase
hr

これを実装すると、以下のアクティビティ一覧が出来上がります。

フォローは相手のプロフィールをリンクにしています。

コメントは、コメント先の投稿をリンクにしていて、自分の投稿に対するコメントは「あなたの投稿」という表現にしています。
自分の投稿なのに「〇〇さんの投稿にコメントしました」という表現は、違和感がありますよね。

これで完成です!
お疲れさまでした!

あわせて読みたい

運営している PlayFab 専用ブログ
https://playfab-master.com