Skip to content

Instantly share code, notes, and snippets.

@superlou
Created July 16, 2012 01:27
Show Gist options
  • Save superlou/3119660 to your computer and use it in GitHub Desktop.
Save superlou/3119660 to your computer and use it in GitHub Desktop.
Reservations fields_for
--- !ruby/object:Reservation
attributes:
id:
event_id: 1231
reservable_type:
reservable_id:
created_at:
updated_at:
inherit_time_span: true
***** Note no time_span_attributes ?!
class Reservation < ActiveRecord::Base
belongs_to :reservable, :polymorphic => true
belongs_to :event
has_one :time_span, :as => :time_spanable
accepts_nested_attributes_for :time_span, :reject_if => proc{|attrs| attrs['start_time'].blank?}
validates :time_span, :presence => true, :unless => :inherit_time_span
validates_presence_of :reservable
def reservable
reservable_type.constantize.find(reservable_id) if reservable_id
end
alias_method :model_time_span, :time_span
def time_span
if inherit_time_span
event.time_span
else
model_time_span
end
end
def scheduled?
return true if time_span
false
end
end
%h1= "Add reservation to #{@event.name}"
= semantic_form_for [@event, @reservation] do |form|
= form.semantic_errors :base
= form.inputs do
= form.input :reservable_id, :as => :select, :collection => reservables_for_select, :selected=>@reservable_compound_id
= form.input :inherit_time_span
- disabled = true if @reservation.inherit_time_span
= form.fields_for :time_span, @time_span do |time_span|
.control-group
%label.control-label Start Time
.controls
= time_span.text_field :start_time, :disabled => disabled
%label.control-label End Time
.controls
= time_span.text_field :end_time, :disabled => disabled
%label.control-label Confidence
.controls
= select_tag "reservation[time_span_attributes][confidence]", options_for_select(TimeSpan::CONFIDENCES), :disabled => disabled
%span.help-inline= t 'formtastic.hints.time_span.confidence'
= form.actions do
= form.action :submit, :as => :button
= form.action :cancel, :as => :link
class ReservationsController < ApplicationController
def new
@event = Event.find(params[:event_id])
@reservation = @event.reservations.build
@reservation.inherit_time_span = true
@reservation.build_time_span
end
def create
reservable = params[:reservation][:reservable_id].split('-')
params[:reservation][:reservable_type] = reservable[0]
params[:reservation][:reservable_id] = reservable[1]
@event = Event.find(params[:event_id])
@reservation = @event.reservations.build(params[:reservation])
if @reservation.save
redirect_to @event, :notice => "Reservation created"
else
@reservable_compound_id = "#{reservable[0]}-#{reservable[1]}"
render :new
end
end
def destroy
@event = Event.find(params[:event_id])
@reservation = Reservation.find(params[:id])
@reservation.destroy
redirect_to @event
end
end
%h1= "Add reservation to #{@event.name}"
= semantic_form_for [@event, @reservation] do |form|
= debug @reservation
= form.inputs do
= form.input :reservable_id, :as => :select, :collection => reservables_for_select, :selected=>@reservable_compound_id
= form.input :inherit_time_span
- disabled = true if @reservation.inherit_time_span
= form.semantic_fields_for :time_span do |time_span|
= time_span.input :start_time, :as => :string, :input_html => { :disabled => disabled }
= time_span.input :end_time, :as => :string, :input_html => { :disabled => disabled }
= time_span.input :confidence, :as => :select, :collection => TimeSpan::CONFIDENCES, :input_html => { :disabled => disabled }
= form.actions do
= form.action :submit, :as => :button
= form.action :cancel, :as => :link
require 'range'
class TimeSpan < ActiveRecord::Base
validates_presence_of :start_time
validates_presence_of :end_time
validates_presence_of :confidence
validate :end_time_follows_start_time
CONFIDENCES = {"tentative" => 0, "likely" => 1, "firm" => 2}
belongs_to :time_spanable, :polymorphic => true
def span
return start_time...end_time
end
def end_time_follows_start_time
errors.add(:end_time, "must follow start time") unless (end_time.to_i > start_time.to_i)
end
def is_during?(time_spans)
time_spans.each do |ts|
return true if ts.span.overlap?(self.span)
end
false
end
def before?(time_span)
return true if end_time < time_span.start_time
false
end
def after?(time_span)
return true if start_time > time_span.end_time
false
end
def duration(resolution = :seconds)
case resolution
when :seconds
duration_in_seconds
when :minutes
duration_in_seconds/60.0
when :hours
duration_in_seconds/3600.0
end
end
def duration_in_seconds
Float(end_time - start_time)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment