👌

[Rails]コミュニティサイト:イベント機能 実装① USERがイベント作成、参加する場合の中間テーブルの作成

2023/03/12に公開

今回、自分が作成するPFの作品の中の機能の一つに、以下の機能がある。

”Userがイベントを作成でき、その作成されたイベントに他のUserが参加する”

この場合の作成方法について解説と、
そもそも中間テーブルとは!?というところも復習していきたいと思う。


今日は①として、作成までを記述していく!!!


中間テーブルの役割

ここはメインではないので、トグルにしてます。
過去に投稿しているので、詳しくはこちらをご覧ください。

中間テーブルの役割

中間テーブルの役割は大きく2つだ。

  1. 多対多の関係を表現するためのもの
  2. 結合条件としての役割を果たすもの

中間テーブルは、それぞれのテーブルの主キーを外部キーとして持ち、両方のテーブルを参照する。
そして、それぞれのテーブルのレコードを組み合わせて、多対多の関係を表現します。
(多:多を中間テーブルが1:Nにする。)

<中間テーブルの特徴>

  • 接続している2つのテーブルのForeign_keyを持っている。
  • null(空)を出すことなく、レコードを追加することができる。
主な用語の説明
用語 意味 補足
リレーションシップ(relationship) 繋がり ここでは、テーブル同士の繋がり(関連)のこと
主キー(PK:Praimary Key) primary:最初の テーブルの情報を一意に識別するためのもの
外部キー(foreign key) foreign: 外国にある 関連したテーブル間を結ぶために設定する列のこと
アソシエーション(association) 繋がり、関連性 異なる 2 つのモデルの間に、1:N の関連性を持たせるもの

association

associationとは
  1. has_manyメソッド
    他のモデルを複数持っている事を定義する

  2. belongs_toメソッド
    他のモデルに属している事を定義する.

  • has_manyでdependent: :destroyをつけると、親モデルが削除された場合に、関連付けられた子モデルも同時に削除されるようになる。
  • 一方、dependent: :destroyをつけない場合は、親モデルが削除されても、関連する子モデルは削除されない。
dependent: :destroyについて
  • 関連するオブジェクトの削除方法を指定するもの。

親モデルが削除された場合に、その子モデルも一緒に削除されるようにする
= というのは、データの整合性を保つことができると言うこと。

あるユーザーが作成したイベントがある場合、そのユーザーが削除された場合に、そのイベントも削除されることで、不要なデータを残すことがなくなります。また、逆にdependent: :destroyをつけない場合、削除された親モデルに紐付いた子モデルが残ってしまい、データの整合性が崩れることがあります。


作成していく!!!

"Userがイベントを作成でき、その作成されたイベントに他のUserが参加する"
ここから整理すると、ER図はこのようになる。

  • users: ユーザー情報を保存するためのテーブル
  • events: イベント情報を保存するためのテーブル
  • attendees: イベントに参加するユーザー情報を保存するための中間テーブル

必要なテーブルとカラムの作成

users
カラム名 カラム説明 PK FK データ型
id 会員id integer
first_name 名前(姓) string
last_name 名前(名) string
first_name_kana 名前(姓) かな string
last_name_kana 名前(名) かな string
email メールアドレス integer
password パスワード integer
introduction 自己紹介文 string
created_at 登録日 timestamp
updated_at 更新日 timestamp

< migration file >

t.string :first_name, null: false, default: ""
t.string :last_name, null: false, default: ""
t.string :first_name_kana, null: false, default: ""
t.string :last_name_kana, null: false, default: ""

t.string :introduction
events
カラム名 カラム説明 PK FK データ型
id イベントID integer
creator_id イベント作成(UserID) integer
date イベント日時 datetime
event_name イベント名 string
event_introduction イベント紹介文 text
Sharing_status 公開範囲 (enum設定) integer
url イベントURL text
created_at 登録日 timestamp
updated_at 更新日 timestamp

enum設定はこのページで解説

< migration file >

class CreateEvents < ActiveRecord::Migration[6.1]
  def change
    create_table :events do |t|
      t.integer :creator_id, null: false
      t.datetime :date, null: false
      t.string :event_name, null: false
      t.text :event_introduction, null: false
      t.text :url, null: false

      t.timestamps
    end
  end
end
attendees(中間テーブル)
カラム名 カラム説明 PK FK データ型
id イベント参加者ID integer
event_id イベントID integer
user_id 会員ID integer
created_at 登録日 timestamp
updated_at 更新日 timestamp

< migration file >

  t.integer :event_id, null: false
  t.integer :user_id, null: false

associationの設定

ER図は、上でも掲載したがこのようになる。これをもとに書いていく。

user

has_many :attendees
has_many :events, through: :attendees
  • 参加者としての関連付けは、Userモデルにhas_manyを定義、throughオプションを用いてAttendanceモデルを経由してEventモデルと関連付け.

  • has_many :through
    => 多対多で別のモデルと関連している従属している第3のモデル(中間テーブル)を介して、対象のモデルと多対多の関連付けを行う。

event

  has_many :attendees
  has_many :users, through: :attendees
  belongs_to :creator, class_name: "User"
  • belongs_to :creator, class_name: "User":イベント作成者としての関連付けを記述。
    外部キーとしてcreator_idを指定

attendee

ユーザーとイベントの参加状況を管理するための中間テーブル。

  belongs_to :user
  belongs_to :event
  • 今回の場合は、dependent: :destroyをつけなくてもよい。
    => 今回のアプリケーションでは、イベントに参加するための中間テーブルであるattendeesテーブルがあるため、イベントを削除すると、関連する参加者情報がattendeesテーブルから自動的に削除されるから。
  • イベントに参加しているユーザー情報を保持するattendeesテーブルにdependent: :destroyをつけることで、データの整合性を保つことができる。

イベントの作成方法!

events controller

class Public::EventsController < ApplicationController
  def new
    @event = Event.new
  end

  def create
    @event = Event.new(event_params)
    @event.creator = current_user #eventの"creator"はログインしているuserだと定義
    if @event.save
      redirect_to event_path(@event)
    else
      render "new"
    end
  end
  :
  :
  private

  def event_params
    params.require(:event).permit(:event_name, :event_introduction, :date, :url)
  end
end
  • @event.creator = current_user
    => eventの"creator"はログインしているuserだと定義しておく。
    これを記述しないとcreatorがnullになるよ!

events/new view画面作成

少々長くて、トグルにしたので開いてねヾ(๑╹◡╹)ノ"

events/new
<div class="container mt-5">
  <div class="row justify-content-center">
    <div class="col-md-8">
      <h2 class="mt-3">Create events</h2>
      <%= form_with model: Event do |f| %>
        <div class="form-group">
          <label for="post_title">
            <h4>Event name</h4>
          </label>
          <%= f.text_field :event_name, class:'form-control event_title' %>
        </div>
        <div class="form-group">
          <label for="event_introduction">
            <h4>introduction</h4>
          </label>
          <%= f.text_area :event_introduction, rows: 10, cols: 10, class: "form-control" %>
        </div>
        <div class="form-group">
          <label for="url">
            <h4>URL</h4>
          </label>
          <%= f.text_field :url, class: "form-control" %>
        </div>
        <div class="form-group">
          <label for="introduction">
            <h4>開催日時</h4>
          </label>
          <%= f.datetime_field :date, class: "form-control" %>
        </div>
        <div class="form-group">
          <%= f.submit '投稿する' ,class: "btn btn-success"%>
        </div>
      <% end %>
    </div>
  </div>
</div>

  • createできたら、showへいくように設定したので、show画面も作成していきます。

を、次回に掲載いたします。(ここに少々山盛りの機能が...手こずりました。)
今日はここまで!

Discussion