私はいくつかのことをします。1 つは、予約ロジックを 1 つのモデルの外に置き、必要なすべてのオブジェクトを入力として取り、すべてのビジネス ロジックをラップするService
orオブジェクトのようにすることです。Manager
class RoomNotAvailableException < StandardError; end
class ReservationService
def initialize(room, customer, arrival, departure)
@room = room
@customer = customer
@arrival = arrival
@departure = departure
end
def reserve!
ActiveRecord::Base.transaction do
if room_available?
Reservation.create(:room => @room, :customer => @customer, :arrival => @arrival, :departure => @departure)
else
raise RoomNotAvailableException
end
end
end
private
def room_available?
Reservation.where(:room_id => @room.id, :arrival => @arrival, :departure => @departure).exists?
end
end
次のようなコントローラーで使用します
def create
# get the objects from params or whatever
service = ReservationService.new(room, customer, arrival, departure)
begin
service.reserve!
flash[:notice] = "You are booked!"
redirect_to('somewhere')
rescue RoomNotAvailableException => ex
# whatever you need to do here..
end
end
2 つ目は、Postgres を使用CHECK CONSTRAINTS
している場合は、チェックを行うために使用できます。2 つの間隔が重ならないようにするため。グーグルで検索する必要がありますが、要点はいくつかの Postgres スレッドで見つけることができます。
http://www.postgresql.org/message-id/20050520162508.GA87868@mighty.grot.org