16832


ホテルの予約システムを実装しており、  
予約情報が格納された`Reservation`と  
その予約情報を元に予約状況を参照するための`ReservedState`を定義してます。

[code]

      # 予約テーブル
      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
    
[/code]

# index.html.slim

[code]

      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
    
[/code]

予約状況(空き状況)を調べるためには下記内容で出力できています。  
`ReservationsController`

[code]

      @reserved_state = ReservedState.new(Reservation.create_day_hash)
    
[/code]

ただし、`ReservedState`は`ActiveModel::Model`であり  
`ActiveRecord::Relation`のように複数の予約情報を保持しておくことが出来ません。  
(ページネーションしたい)

  * [選択肢1] `ActiveModel::Model`で複数のデータが入るようにする。
  * [選択肢2] `ActiveRecord::Base`を継承したモデルを作り、それ用のテーブルも作る

この場合、どのような実装にすれば良いでしょうか。


CC BY-SA 3.0
2015-09-20T03:54:26.080
16786
2015-09-21T20:15:59.720
2015-09-21T12:45:20.583
9177
9177
question
ruby-on-rails rails-activerecord
ActiveModelをActiveRecord::Relationのように複数(collection)にして参照したい。


「本当は - @reserved_states.each do |r|
でCollection回したい」とありますが、単純にコントローラーの中でReservedStateを複数作って配列にすればよいのでは？と思いました。

[code]

    # Controller
    def index
      # 今日から7日先までの予約データを集める
      @reserved_states = 7.times.map {|n|
        ReservedState.new(Reservation.create_day_hash(Time.current.since(n.days))) 
      }
    end
    
[/code]

「いやいや、それだとダメなんです」という場合はもう少し詳しくやりたいことを追記してください。


CC BY-SA 3.0
2015-09-21T20:15:59.720
16832
2015-09-21T20:15:59.720
85
16786
answer