0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

初学者メモ Rails グループ作成機能

Posted at

はじめに

「コミュニティアプリにグループ作成機能を実装したい」
「グループへ自由に入会、退会できるようにしたい」
初学者のメモです

実装した主な機能

  • オーナーによるグループ作成、削除
  • グループ情報は、「イメージ画像」「グループ名」「グループ説明」
  • オーナー以外のグループへの入会、退会

手順

  1. アソシエーション
  2. ルーティング
  3. コントローラー(グループ作成)
  4. コントローラー(グループ入会、退会)

実装

ER図

diagrams.netで作成
スクリーンショット 2023-06-04 10.05.11.png

  • このイメージで実装していきます
  • 元々、Userモデルがある状態です
  • Userにownerカラムを持たせるか悩みました(結局、必要なかったです)

① アソシエーション

user.rb
#省略
has_many :group_users, dependent: :destroy
has_many :groups, through: :group_users
#省略
  • userは中間テーブルgroup_usersを介して、groupsを持っているというイメージ
  • ブックマーク機能やフォロー機能との関連性を感じます
過去にフォロー機能を作成したときのもの

スクリーンショット 2023-06-04 11.45.42.png

group.rb
belongs_to :owner, class_name: 'User'
has_many :group_users, dependent: :destroy
has_many :users, through: :group_users, source: :user
validates :name, presence: true
validates :introduction, presence: true
has_one_attached :image

def get_image
  (image.attached?) ? image : 'no_image.jpg'
end
  • belongs_to :owner, class_name: 'User'は、groupはownerを持っていて、それは、userモデルにあるというイメージ。中間テーブルにowner_idがあることで実現できる
  • groupは中間テーブルgroup_usersを介して、usersを持っているというイメージ。ここも、ブックマーク機能やフォロー機能との関連性を感じます
  • バリデーションもOK
  • 今回は、Active Recordにimageカラムを持たせたため、has_one_attached :image の記述と、get_imageのアクション定義をしています。画像添付がない場合は、no_image.jpgを参照
group_user.rb
belongs_to :user
belongs_to :group

②ルーティング

routes.rb
resources :groups do
  resource :group_users, only: [:create, :destroy]
end
  • Groupについては、デフォルトのアクションを全て可能にしました
  • group_usersについては、「create=グループ入会」「destroy=グループ退会」のみにしました

③コントローラー(グループ作成)

groups_controller/rb
before_action :authenticate_user!
before_action :ensure_correct_user, only: [:edit, :update]

def new
  @group = Group.new
end

def index
  @groups = Group.all
end

def show
  @group = Group.find(params[:id])
end

def create
  @group = Group.new(group_params)
  @group.owner_id = current_user.id
  @group.users << current_user
    if @group.save
      redirect_to groups_path
    else
      render 'new'
    end
end

def edit
end

def update
  if @group.update(group_params)
    redirect_to groups_path
  else
    render "edit"
  end
end

def destroy
  @group = Group.find(params[:id])
  @group.destroy
  redirect_to groups_path
end

private

def group_params
  params.require(:group).permit(:name, :introduction, :image)
end

def ensure_correct_user
  @group = Group.find(params[:id])
  unless @group.owner_id == current_user.id
    redirect_to groups_path
  end
end
  • @group.users << current_userで、現在のユーザーをグループのユーザー数に追加しました
  • これで、グループのcreateもdestroyも可能になります

④コントローラー(グループ入会、退会)

group_users_controller.rb
before_action :authenticate_user!
  
def create
  group_user = current_user.group_users.new(group_id: params[:group_id])
  group_user.save
  redirect_to request.referer
end
  
def destroy
  group_user = current_user.group_users.find_by(group_id: params[:group_id])
  group_user.destroy
  redirect_to request.referer
end
  • find_by(group_id: params[:group_id])では、find_byメソッドでによって、group_idを指定しました
  • HTTPリファラを取得してリダイレクトさせるredirect_to request.refererが個人的に便利で好きです
  • 後は、ビューファイルの記述

まとめ

  • グループ機能は中間テーブルを用いて、N対Nのリレーションを実装する
  • グループ作成はgroupsに、入会や退会はgroup_usersにアクションを記述する

投稿4回目。
ボリューミーで、整理するのが難しかったです。
今後、グループ内での様々な機能を試していきます。
ご指導、ご教授いただけると幸いです。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?