LoginSignup
4
3

More than 1 year has passed since last update.

グループ招待機能の実装方法

Posted at

※ 初めて書いた記事ですので、間違い等あればご指摘いただけますと幸いです。

概要

通知機能を利用して、チーム機能に招待機能を実装する。

前提

  • ユーザー機能を実装済み
  • チーム機能を実装済み
  • 通知機能を実装済み

参考記事

通知機能はこちらの記事を参考させていただきました。
【Rails】通知機能を誰でも実装できるように解説する【いいね、コメント、フォロー】

通知モデルの概要

以下、テーブル情報の例です。

visitor_id visited_id post_id comment_id action checked
1 2 nil nil follow false
1 2 3 nil like false
1 2 nil nil comment false
  • visitor_id:通知を送ったユーザーのID
  • visited_id:通知を送られた(受け取る)ユーザーのID
  • post_id:いいねされた投稿
  • comment_id:投稿へのコメントID
  • action:通知の種類(ここではfollow,like,comment
  • checked:通知を確認したかどうか

この記事の招待機能の概要

チームに加入できるリンクが付いている通知を送る。

visitor_id visited_id team_id action checked
1 2 1 invitaion false
  1. 上記のようなテーブル情報を持つ通知を生成し、通知一覧に表示させる。

  2. 通知に記載されているリンクを踏むと招待されたチームに加入する。

このような流れでチームへの招待を実装します。

実装の手順

  1. ルーティングを設定。(config/routes.rb)
  2. 通知生成用のメソッドを作成。(app/models)
  3. コントローラに処理を記述。(app/controllers)
  4. フォームを記述。(app/views)

本記事ではこの順番で実装を進めていきます。

実装

  • ルーティングの設定。
config/routes.rb
resources :teams, only: [:index, :show, :new, :create, :edit, :update] do
    get  :join
    post :invitation
end

招待通知を生成するためのアクションinvitation
チームに加入する処理を行うアクションjoin
上記の2つのアクションのルーティングを記述します。

  • 通知生成用のメソッドを作成。
app/models/team.rb
def team_invitation_notification(current_user, visited_id, team_id)
    # すでに招待用の通知が送られているか検索。
    temp = Notification.where(visitor_id: current_user.id, visited_id: visited_id, team_id: team_id)
      # 上記で検索した通知がない場合のみ、通知レコードを作成。
    if temp.blank?
      notification = current_user.active_notifications.new(
        visited_id: visited_id,
        team_id: team_id,
        action: "invitation",
      )
      # エラーがなければ、通知レコードを保存。
      notification.save if notification.valid?
    end
  end
end


  • コントローラに処理を記述。

招待通知生成の処理を行うinvitationアクションを記述。

app/controllers/teams_controller.rb
    def invitation
        @team = Team.find(params[:id])
                # この後 view に設置するフォームの値を参照する。
        @user = User.find_by(id: params[:user_id])
        notification = Notification.where(visited_id: @user.id, team_id: @team.id, action: "invitation")
        unless notification.exists?
          # それぞれの仮引数を置き換えて、team.rb に記述したメソッドを呼び出す。
          @team.team_invitation_notification(current_user, @user.id, @team.id)
          # 遷移する前のURLを取得し、リダイレクトさせる。
          redirect_to request.referer, notice: "招待を送りました。"
        else
          redirect_to request.referer, alert: "すでに招待しています。"
        end
     end


チーム加入処理を行うjoinアクションを記述。

app/controllers/teams_controller.rb
    def join
        @team = Team.find(params[:id])
        # @team.users に、current_user のレコードが含まれていなければ以下の処理を行う。
        unless @team.users.include?(current_user)
                    # @team.users に、current_user のレコードを追加する。
          @team.users << current_user
            # 招待通知を検索して削除。
          notification = Notification.find_by(visited_id: current_user.id, team_id: @team.id, action: "invitation")
          notification.destroy
        end
        redirect_to team_path(@team), notice: "チームに参加しました。"
      end


  • フォームを記述。
app/views/teams/show.html.erb
# @other_users は、チームに所属していないユーザーの値を取得している。

<% if @other_users.exists? %>
  <%= form_with model: @user, url: invitation_team_path(@team), method: :post, local: true do |f| %>
    <%= f.collection_select :user_id, @other_users, :id, :nickname %>
    <%= f.submit "招待する" %>
  <% end %>
<% end %>


  • 実際に表示される通知を記述。

actionカラムの値によって表示する内容を変えるようにしたいので、case文を使って表示を分岐させます。

app/views/notifications/_notification.html.erb
    <% case notification.action %>
        <% when "invitaion" %>
            <%= link_to "visitor.name", user_path(visitor) %>
            さんからチームへの招待が届きました。
            # このリンクをクリックすると、チーム加入処理を行う join アクションが働く。
            <%= link_to "参加する", team_join_path(notification.team_id) %>



以下の記述は、<% if notification.action == "invitation" %>と同義です。

<% case notification.action %>
        <% when "invitaion" %>

通知機能のように、分岐が多い場合にはcase文を用いる方が良いと思います。


実装の工程は以上です。
お疲れ様でした。

初学者が考えた程度のものですので、足りないところが多々あるかと存じますが、どなたかのお役に立てば幸いです。

4
3
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
4
3