[Rails]コミュニティサイト:イベント機能 実装① USERがイベント作成、参加する場合の中間テーブルの作成
今回、自分が作成するPFの作品の中の機能の一つに、以下の機能がある。
”Userがイベントを作成でき、その作成されたイベントに他のUserが参加する”
この場合の作成方法について解説と、
そもそも中間テーブルとは!?というところも復習していきたいと思う。
今日は①として、作成までを記述していく!!!
中間テーブルの役割
ここはメインではないので、トグルにしてます。
過去に投稿しているので、詳しくはこちらをご覧ください。
中間テーブルの役割
中間テーブルの役割は大きく2つだ。
- 多対多の関係を表現するためのもの
- 結合条件としての役割を果たすもの
中間テーブルは、それぞれのテーブルの主キーを外部キーとして持ち、両方のテーブルを参照する。
そして、それぞれのテーブルのレコードを組み合わせて、多対多の関係を表現します。
(多:多を中間テーブルが1:Nにする。)
<中間テーブルの特徴>
- 接続している2つのテーブルのForeign_keyを持っている。
- null(空)を出すことなく、レコードを追加することができる。
主な用語の説明
用語 | 意味 | 補足 |
---|---|---|
リレーションシップ(relationship) | 繋がり | ここでは、テーブル同士の繋がり(関連)のこと |
主キー(PK:Praimary Key) | primary:最初の | テーブルの情報を一意に識別するためのもの |
外部キー(foreign key) | foreign: 外国にある | 関連したテーブル間を結ぶために設定する列のこと |
アソシエーション(association) | 繋がり、関連性 | 異なる 2 つのモデルの間に、1:N の関連性を持たせるもの |
association
associationとは
-
has_manyメソッド
他のモデルを複数持っている事を定義する -
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 | ||
メールアドレス | 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 |
< 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>
- 日時は入力間違いがないように、
datetime_field
を使用していきます。
Rails ガイド:datetime_fieldはここから!
- createできたら、showへいくように設定したので、show画面も作成していきます。
を、次回に掲載いたします。(ここに少々山盛りの機能が...手こずりました。)
今日はここまで!
Discussion