LoginSignup
1
3

More than 1 year has passed since last update.

【Rails6】多対多のアソシエーションを利用したグループ参加機能の実装

Last updated at Posted at 2021-03-21

※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!!」のフラッシュメッセージが出る。

これでグループへの参加が完了です。
Image from Gyazo
それでは説明していきます。
グループ参加機能の実装に関係する記述以外は省略しているのでご承知おきください。

実装手順1:モデルの作成

用意するモデル(テーブル)はuser, group, user_groupの3つです。

app/models/user.rb
class User < ApplicationRecord
  has_many :user_groups
  has_many :groups, through: :user_groups
end
app/models/group.rb
class Group < ApplicationRecord
  has_many :user_groups
  has_many :users, through: :user_groups
end
app/models/user_group.rb
class UserGroup < ApplicationRecord
  belongs_to :user
  belongs_to :group

  validates :user_id, uniqueness: { scope: :group_id }
end

実装手順2:コントローラーの作成

groups_controlleruser_groups_controllerを以下のように記述します。グループ参加機能の実装には、users_controllerへの記述は特にありません。

app/controllers/groups_controller.rb
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
app/controllers/user_groups_controller.rb
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.rbparams[:group_id]をを使用するアクションを定義しているため、user_groupsコントローラーgroupsコントローラーにネストさせます。

config/routes.rb
Rails.application.routes.draw do
  resources :groups, only: :show do
    resources :user_groups, only: :create
  end
end

実装手順4:ビューの作成

ボタンの部分の記述だけ掲載します。
条件分岐で@userGroupに値が入っていれば、グループに参加しているのでグループメンバーしか見られない情報を表示し、値が入っていなければで「Join the group」ボタンを表示します。

app/views/groups/show.html.erb
<% 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 %>

これでグループ参加機能の実装完了です。

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