tamuraです。
Ruby on Railsの勉強をかねて、ben33を作り直してみます。



インストールとか

anyenvとかで済ませているので割愛しますが、なんというか意外と大変でした。

プロジェクトの作成

rails new ben33

データベース

ユーザ情報

メールアドレスと4桁以上のPINを入力すると、登録時のメールアドレスに一時的な認証URLが送られてくる仕組みにしたいと思います。

$ rails generate model user email:string pin:string username:string last_login:datetime

イベント情報

イベント名など。 イベント画像とかを貼れるようにしたいけどまたあとでやります。

$ rails generate model event event_name:string start_date:datetime end_date:datetime venue:string created_by:integer

参加者情報

ユーザ情報とイベント情報を多対多でつなぐテーブルです。 多対多はhas_manyhas_many throughbelongs_toを使えばできるとのことです。

$ rails generate model attend user_id:integer event_id:integer attend_type:string comment:string

ユーザ情報の変更

has_manyをつけます。

class User < ApplicationRecord
  has_many :attends
  has_many :event, through: :attends
end

イベント情報

こちらも同じくhas_manyをつけます。

class Event < ApplicationRecord
  has_many :attends
  has_many :users, through: :attends
end

参加者情報

belongs_toをつけます。

class Attend < ApplicationRecord
  belongs_to :user
  belongs_to :event
end

動作確認

テストデータ投入

db/seeds.rb でテストデータを投入します。

users = User.create(
  [
    {email: 'sample-0001@sample.com', pin: '0001', username: 'サンプル1号'},
    {email: 'sample-0002@sample.com', pin: '0002', username: 'サンプル2号'},
    {email: 'sample-0003@sample.com', pin: '0003', username: 'サンプル3号'}
  ]
)

events = Event.create(
  [
    {event_name: 'サンプルイベント1', start_date: '2018-01-01 19:00:00', end_date: '2018-01-01 21:00:00', venue: '五反田'},
    {event_name: 'サンプルイベント2', start_date: '2018-01-02 19:00:00', end_date: '2018-01-02 21:00:00', venue: '大崎'},
    {event_name: 'サンプルイベント3', start_date: '2018-01-03 19:00:00', end_date: '2018-01-03 21:00:00', venue: '品川'}
  ]
)

attends = Attend.create(
  [
    {user_id: users[0].id, event_id: events[0].id, attend_type: '参加', comment: '参加します!'},
    {user_id: users[1].id, event_id: events[0].id, attend_type: 'キャンセル', comment: 'やっぱり参加できなくなりました。。。'},
    {user_id: users[2].id, event_id: events[0].id, attend_type: '参加', comment: '参加します!'},
    {user_id: users[0].id, event_id: events[1].id, attend_type: '参加', comment: '参加します!'}
  ]
)

これを

$ rake db:seed

これで投入します。

テストデータをいったん消したいときは以下のコマンドでいいそうです。

$ rake db:migrate:reset

コントローラ

$ rails generate controller event list
class EventController < ApplicationController
  def list
    @events = Event.all
  end
end

Eventから全データを抜いてくるだけです。

ビュー

<h1>Event#list</h1>
<hr/>

<% @events.each do |event| %>
イベントID: <%= event.id %><br />
イベント名: <%= event.event_name %><br />
開始日時: <%= event.start_date %><br />
終了日時: <%= event.end_date %><br />
場所: <%= event.venue %><br />
<ul>
<% event.attends.each do |attend| %>
<li><%= attend.user.username %> : <%= attend.attend_type %> : <%= attend.comment %></li>
<% end %>
</ul>
<hr />
<% end %>

イベント情報とそれに紐づく参加者情報を抜いてくるだけです。

実行

$ bundle exec rails server

screen

おk

なんかSQL発行しまくりでこれが噂のN+1問題か?と思うのですが、とりあえずおk。

余談

@events = Event.all.includes(:attends, :users) にしたらおさまりました。