11
21

More than 3 years have passed since last update.

rails グループ機能の実装

Posted at

グループ機能の実装について書きます。
基本自分がやってきた内容の備忘録なので
内容が足りないところがありますが、御愛敬で

目次

1.コントローラ、モデルを作成する
2.ルーティングを設定する
3.グループに関するビューを作成
4.グループ作成機能を実装する
5.ルーティングを変更し、作成したグループをgroups#indexのサイドバーに表示する
6.グループ編集機能を実装する

1.コントローラ、モデルを作成

必要ファイルの作成

まず三つのコマンドを行い。作成する

ターミナル
$ rails g controller groups
$ rails g model group
$ rails g model group_user

モデルからのデータベースの作成

groupモデルのマイグレーションファイル
class CreateGroups < ActiveRecord::Migration[5.2]
  def change
    create_table :groups do |t|
      t.string :name, null: false
      t.index :name, unique: true
      t.timestamps
    end
  end
end
group_userモデルのマイグレーションファイル
class CreateGroupUsers < ActiveRecord::Migration[5.2]
  def change
    create_table :group_users do |t|
      t.references :group, foreign_key: true
      t.references :user, foreign_key: true
      t.timestamps
    end
  end
end
ターミナル
$ rails db:migrate

アソシエーションの定義

app/models/group.rb
class Group < ApplicationRecord
  has_many :group_users
  has_many :users, through: :group_users
  validates :name, presence: true, uniqueness: true
end
/models/group_user.rb
class GroupUser < ApplicationRecord
  belongs_to :group
  belongs_to :user
end
/models/user.rb
class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable,  :validatable

  has_many :group_users
  has_many :groups, through: :group_users
end

2.ルーティングを設定する

グループに置いて下記を行う。

new:新規作成画面を表示する
create:新規作成されたグループを保存する
edit:編集画面を表示する
update:編集されたグループを更新する

routes.rb
Rails.application.routes.draw do
  devise_for :users
  root 'messages#index'
  resources :users, only: [:index, :edit, :update]
  resources :groups, only: [:new, :create, :edit, :update] # ここで設定する。
end

3. グループに関するビューを作成

4. グループ作成機能を実装する

groups_controller.rb
class GroupsController < ApplicationController
  def new
    @group = Group.new
    @group.users << current_user
  end

  def create
    @group = Group.new(group_params)
    if @group.save
      redirect_to root_path, notice: 'グループを作成しました'
    else
      render :new
    end
  end

  private
  def group_params
    params.require(:group).permit(:name, user_ids: [] )
  end
end

エラーメッセージの表示

app/views/groups/new.html.haml
.chat-group-form
  %h1 新規チャットグループ
# 〜省略〜
groups/new.html.haml
.chat-group-form
  %h1 新規チャットグループ
  = form_for @group do |f|
    - if @group.errors.any?
      .chat-group-form__errors
        %h2= "#{@group.errors.full_messages.count}件のエラーが発生しました。"
        %ul
          - @group.errors.full_messages.each do |message|
            %li= message
    .chat-group-form__field
      .chat-group-form__field--left
        = f.label :name, "グループ名", class: 'chat-group-form__label'
      .chat-group-form__field--right
        = f.text_field :name, class: 'chat__group_name chat-group-form__input', placeholder: 'グループ名を入力してください'
    .chat-group-form__field.clearfix
      / この部分はインクリメンタルサーチ(ユーザー追加の非同期化)のときに使用します
    .chat-group-form__field.clearfix
      .chat-group-form__field--left
        = f.label "チャットメンバー", class: "chat-group-form__label"
      .chat-group-form__field--right
        / グループ作成機能の追加時はここにcollection_check_boxesの記述を入れてください
        = f.collection_check_boxes :user_ids, User.all, :id, :name
        / この部分はインクリメンタルサーチ(ユーザー追加の非同期化)のときにも使用します
    .chat-group-form__field.clearfix
      .chat-group-form__field--left
      .chat-group-form__field--right
        = f.submit class: 'chat-group-form__action-btn'

5. ルーティングを変更し、作成したグループをgroups#indexのサイドバーに表示する

ルーティングの編集
これまでに指定していたmessages#indexへのルーティングを外し
代わりにroot 'groups#index'を指定します。

routes.rb
Rails.application.routes.draw do
  devise_for :users
  root 'groups#index'
  resources :users, only: [:index, :edit, :update]
  resources :groups, only: [:new, :create, :edit, :update] 
end
groups_controller.rb
class GroupsController < ApplicationController
  def index # ここを追加
  end

  def new
    @group = Group.new
    @group.users << current_user
  end

  def create
    @group = Group.new(group_params)
    if @group.save
      redirect_to root_path, notice: 'グループを作成しました'
    else
      render :new
    end
  end

  private
  def group_params
    params.require(:group).permit(:name, user_ids: [] )
  end
end
app/views/groups/index.html.haml
.wrapper
  = render 'shared/side_bar'
views/shared/_side_bar.html.haml
.side-bar
  .header
    %h3.header__name
      = current_user.name
    %ul.header__lists
      %li.list
        = link_to new_group_path do
          = icon('fas', 'pen-square', class: 'icon')
      %li.list
        = link_to edit_user_path(current_user) do
          = icon('fas', 'cog', class: 'icon')
  / ここから下を編集
  .groups 
    - current_user.groups.each do |group|
      .group
        = link_to '#' do
          .group__name
            = group.name
          .group__message
            メッセージはまだありません。

6,グループ編集機能の実装

groups_controller.rb
class GroupsController < ApplicationController
  before_action :set_group, only: [:edit, :update] # ここ1

#〜省略〜

  def update # ここ2
    if @group.update(group_params)
      redirect_to root_path, notice: 'グループを更新しました'
    else
      render :edit
    end
  end

  private

  def group_params
    params.require(:group).permit(:name, { :user_ids => [] })
  end

  def set_group # ここ3
    @group = Group.find(params[:id])
  end
end

グループの作成と編集画面のフォームを共通化

views/groups/_form.html.haml
= form_for group do |f|
  - if group.errors.any?
    .chat-group-form__errors
      %h2= "#{group.errors.full_messages.count}件のエラーが発生しました。"
      %ul
        - group.errors.full_messages.each do |message|
          %li= message
  .chat-group-form__field
    .chat-group-form__field--left
      = f.label :name, class: 'chat-group-form__label'
    .chat-group-form__field--right
      = f.text_field :name, class: 'chat__group_name chat-group-form__input', placeholder: 'グループ名を入力してください'
  .chat-group-form__field.clearfix
    / この部分はインクリメンタルサーチ(ユーザー追加の非同期化のときに使用します
  .chat-group-form__field.clearfix
    .chat-group-form__field--left
      %label.chat-group-form__label{:for => "chat_group_チャットメンバー"} チャットメンバー
    .chat-group-form__field--right
      / グループ作成機能の追加時はここにcollection_check_boxesの記述を入れてください
      = f.collection_check_boxes :user_ids, User.all, :id, :name
      / この部分はインクリメンタルサーチ(ユーザー追加の非同期化のときに使用します
  .chat-group-form__field.clearfix
    .chat-group-form__field--left
    .chat-group-form__field--right
      = f.submit class: 'chat-group-form__action-btn'
groups/edit.html.haml
.chat-group-form
  %h1 チャットグループ編集
  = render partial: 'form', locals: { group: @group }
groups/new.html.haml
.chat-group-form
  %h1 新規チャットグループ
  = render partial: 'form', locals: { group: @group }
11
21
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
11
21