※2022年から技術系の記事は個人ブログに投稿しております。ぜひこちらもご覧ください→yamaday0u Blog
多対多のアソシエーションを利用してグループ参加機能を実装する方法を紹介します。
目次
- 前提条件
- グループ参加機能の仕様
- 動作確認
- 実装手順1:モデルの作成
- 実装手順2:コントローラーの作成
- 実装手順3:ルーティングの設定
- 実装手順4:ビューの作成
前提条件
Rails 6.0.3.5
グループ参加機能の仕様
承認制ではなく、グループに参加するボタンをクリックすると、データベースにユーザーIDとグループIDに組み合わせが保存されて参加できる簡単なものになります。
動作確認
- 「Join this group」をクリック
- Are you sure to join this group?」というメッセージが出る
- OKをクリックするとグループのトップページに移動する
- 「Notice: joined the group!!」のフラッシュメッセージが出る。
これでグループへの参加が完了です。
それでは説明していきます。
グループ参加機能の実装に関係する記述以外は省略しているのでご承知おきください。
実装手順1:モデルの作成
用意するモデル(テーブル)はuser, group, user_groupの3つです。
class User < ApplicationRecord
has_many :user_groups
has_many :groups, through: :user_groups
end
class Group < ApplicationRecord
has_many :user_groups
has_many :users, through: :user_groups
end
class UserGroup < ApplicationRecord
belongs_to :user
belongs_to :group
validates :user_id, uniqueness: { scope: :group_id }
end
実装手順2:コントローラーの作成
groups_controller
とuser_groups_controller
を以下のように記述します。グループ参加機能の実装には、users_controller
への記述は特にありません。
class GroupsController < ApplicationController
def show
@group = Group.find(params[:id])
# UserGroupテーブルからログインユーザーと、詳細を表示しているグループの組み合わせを探します。
# 組み合わせがなければnilを返します。
@userGroup = UserGroup.find_by(user_id: current_user.id, group_id: params[:id])
end
class UserGroupsController < ApplicationController
def create
@userGroup = UserGroup.new(user_id: current_user.id, group_id: params[:group_id])
if @userGroup.save
# グループ参加後のリダイレクト先を指定
redirect_to XXXX_path(@userGroup.group_id), notice: 'joined the group!!'
end
end
end
実装手順3:ルーティングの設定
user_groups_controller.rb
でparams[:group_id]
をを使用するアクションを定義しているため、user_groupsコントローラー
をgroupsコントローラー
にネストさせます。
Rails.application.routes.draw do
resources :groups, only: :show do
resources :user_groups, only: :create
end
end
実装手順4:ビューの作成
ボタンの部分の記述だけ掲載します。
条件分岐で@userGroup
に値が入っていれば、グループに参加しているのでグループメンバーしか見られない情報を表示し、値が入っていなければで「Join the group」ボタンを表示します。
<% if @userGroup.present? %>
<div class="form-group">
<div class="schedule-item">
<div class="schedule-item-header text-left">
<p class="bold">Task</p>
</div>
<div class="schedule-item-body text-left">
<p><%= @group.task %></p>
</div>
</div>
</div>
<% else %>
<div class="actions">
<%# user_groupsコントローラーのcreateアクションを実行するリンク %>
<%= link_to 'Join this group', group_user_groups_path(@group.id), method: :post, data: { confirm: 'Are you sure to join this group?'}, class:"sign-up-btn" %>
</div>
<% end %>
これでグループ参加機能の実装完了です。