ActiveModelをActiveRecord::Relationのように複数(collection)にして参照したい。
ホテルの予約システムを実装しており、
予約情報が格納されたReservation
と
その予約情報を元に予約状況を参照するためのReservedState
を定義してます。
# 予約テーブル
class Reservation < ActiveRecord::Base
# ~略~ 部屋idや 予約開始(終了)時刻等が定義されている
scope :reservable, -> (time = Time.current) {
where(arel_table[:started_at].lteq(time))
.where(arel_table[:ended_at].gteq(time.advance(minutes: 60)))
# TODO: 60min以外でも検知出来るようにする
}
# 予約可能か
def self.reservable?(time)
reservable(time).empty?
end
def self.create_day_hash(day = Time.current)
hash = {}
hash[:dated_at] = day
0.upto(24) do |hour|
# ex) hash[:hour00] = true
hash['hour' + hour.to_s.rjust(2, '0')] = reservable?(day.change(hour: hour))
end
hash
end
end
# 予約情報モデル
class ReservedState
include ActiveModel::Model
attr_accessor :dated_at,
# その他 予約時間を参照するためのBooleanカラム :hour00 ~ :hour23
def initialize(attributes={})
super
end
end
index.html.slim
table
thead
tr
th 時間
th = @reserved_state.dated_at
/ 本当は - @reserved_states.each do |r| でCollection回したい
tbody
- 0.upto(23).each do |x|
tr
td = "#{x.to_s.rjust(2, '0')}:00"
td = @reserved_state.special_hour(x.to_s.rjust(2, '0'))
# ~ 略 ~
class ReservedStateDecorator < Draper::Decorator
delegate_all
def special_hour(hour)
object.send("hour#{hour}") ? '○' : '×'
end
end
予約状況(空き状況)を調べるためには下記内容で出力できています。
ReservationsController
@reserved_state = ReservedState.new(Reservation.create_day_hash)
ただし、ReservedState
はActiveModel::Model
であり
ActiveRecord::Relation
のように複数の予約情報を保持しておくことが出来ません。
(ページネーションしたい)
- [選択肢1]
ActiveModel::Model
で複数のデータが入るようにする。 - [選択肢2]
ActiveRecord::Base
を継承したモデルを作り、それ用のテーブルも作る
この場合、どのような実装にすれば良いでしょうか。