Created
March 5, 2009 11:55
-
-
Save jamesu/74325 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Some people have been emailing me complaining that my calendar_helper code | |
# (http://gist.github.com/54116) doesn't work properly. | |
# | |
# So for all of you who can't perform a little bit of problem solving to get the code working correctly in your app, here is the code as used in a fork of RuckSack. | |
# Enjoy. | |
#== | |
# Copyright (C) 2009 James S Urquhart | |
# | |
# Permission is hereby granted, free of charge, to any person | |
# obtaining a copy of this software and associated documentation | |
# files (the "Software"), to deal in the Software without | |
# restriction, including without limitation the rights to use, | |
# copy, modify, merge, publish, distribute, sublicense, and/or sell | |
# copies of the Software, and to permit persons to whom the | |
# Software is furnished to do so, subject to the following | |
# conditions: | |
# | |
# The above copyright notice and this permission notice shall be | |
# included in all copies or substantial portions of the Software. | |
# | |
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES | |
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | |
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | |
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
# OTHER DEALINGS IN THE SOFTWARE. | |
#++ | |
# calendars_controller.rb | |
class CalendarsController < ApplicationController | |
# GET /calendars | |
# GET /calendars.xml | |
def index | |
@calendars = Calendar.find(:all) | |
respond_to do |format| | |
format.html # index.html.erb | |
format.xml { render :xml => @calendars } | |
end | |
end | |
# GET /calendars/1 | |
# GET /calendars/1.xml | |
def show | |
@calendar = Calendar.find(params[:id]) | |
respond_to do |format| | |
format.html # show.html.erb | |
format.xml { render :xml => @calendar } | |
end | |
end | |
# GET /calendars/new | |
# GET /calendars/new.xml | |
def new | |
@calendar = Calendar.new | |
respond_to do |format| | |
format.html # new.html.erb | |
format.xml { render :xml => @calendar } | |
end | |
end | |
# GET /calendars/1/edit | |
def edit | |
@calendar = Calendar.find(params[:id]) | |
end | |
# POST /calendars | |
# POST /calendars.xml | |
def create | |
@calendar = Calendar.new(params[:calendar]) | |
@calendar.created_by = @logged_user | |
@calendar.color ||= "\#%06x" % (rand() * 0xFFFFFF).to_i | |
respond_to do |format| | |
if @calendar.save | |
flash[:notice] = 'Calendar was successfully created.' | |
format.html { redirect_to(@calendar) } | |
format.js { @calendars = Calendar.find(:all) } | |
format.xml { render :xml => @calendar, :status => :created, :location => @calendar } | |
else | |
format.html { render :action => "new" } | |
format.js | |
format.xml { render :xml => @calendar.errors, :status => :unprocessable_entity } | |
end | |
end | |
end | |
# PUT /calendars/1 | |
# PUT /calendars/1.xml | |
def update | |
@calendar = Calendar.find(params[:id]) | |
@calendar.updated_by = @logged_user | |
respond_to do |format| | |
if @calendar.update_attributes(params[:calendar]) | |
flash[:notice] = 'Calendar was successfully updated.' | |
format.html { redirect_to(@calendar) } | |
format.xml { head :ok } | |
else | |
format.html { render :action => "edit" } | |
format.xml { render :xml => @calendar.errors, :status => :unprocessable_entity } | |
end | |
end | |
end | |
# DELETE /calendars/1 | |
# DELETE /calendars/1.xml | |
def destroy | |
@calendar = Calendar.find(params[:id]) | |
@calendar.updated_by = @logged_user | |
@calendar.destroy | |
respond_to do |format| | |
format.html { redirect_to(calendars_url) } | |
format.xml { head :ok } | |
end | |
end | |
end | |
# events_controller.rb | |
class EventsController < ApplicationController | |
layout 'pages' | |
def calc_cbtw(first, second) | |
if first > second | |
second + (7 - first) | |
else | |
second - first | |
end | |
end | |
def calc_bow(date, start = 1) | |
days_to_beg = calc_cbtw(start, date.wday) | |
date - days_to_beg | |
end | |
# GET /events | |
# GET /events.xml | |
def index | |
@month = params[:month].nil? ? Time.now.month : params[:month].to_i | |
@year = params[:year].nil? ? Time.now.year : params[:year].to_i | |
@content_for_sidebar = 'event_sidebar' | |
# Start of month, end of month | |
@now_date = Date.civil(@year, @month) | |
@prev_date = @now_date - 1.month | |
@prev_date = Date.civil(@prev_date.year, @prev_date.month, -1) | |
@next_date = @now_date + 1.month | |
@next_date = Date.civil(@next_date.year, @next_date.month) | |
# Note: works up till 6 | |
@first_day_of_week = 1 | |
# offset by weekdays | |
@strip_start = calc_bow(@now_date, @first_day_of_week) | |
@next_date = calc_bow(@next_date + 7, @first_day_of_week)-1 | |
@event_strips = [[nil] * (@next_date - @strip_start + 1)] | |
@calendars = Calendar.find(:all) | |
if params[:calendar].nil? | |
@calendar_ids = @calendars.collect {|c| c.id} | |
else | |
@calendar_ids = (params[:calendar] || "").split(',').collect {|id| id.to_i} | |
end | |
@events = Event.find(:all, | |
:include => :calendar, | |
:conditions => ['calendar_id IN (?) AND ((start_date >= ? AND start_date < ?) OR | |
(end_date NOT NULL AND | |
(end_date > ? AND start_date < ?) | |
))', | |
@calendar_ids, | |
@strip_start, @next_date, | |
@strip_start, @next_date+1], :order => 'start_date ASC').collect do |evt| | |
cur_date = evt.start_date.to_date | |
end_date = evt.to_date | |
cur_date, end_date = evt.clip_range(@strip_start, @next_date) | |
range = ((cur_date - @strip_start).to_i)...((end_date - @strip_start).to_i) | |
# Find strip | |
found_strip = nil | |
for strip in @event_strips | |
is_in = true | |
range.each do |r| | |
if !strip[r].nil? | |
is_in = false | |
break | |
end | |
end | |
if is_in | |
found_strip = strip | |
break | |
end | |
end | |
# Make strip or add to found strip | |
if !found_strip.nil? | |
range.each {|r| found_strip[r] = evt} | |
else | |
found_strip = [nil] * (@next_date - @strip_start + 1) | |
range.each {|r| found_strip[r] = evt} | |
@event_strips << found_strip | |
end | |
evt | |
end | |
#for strip in @event_strips | |
# puts strip.collect {|s| s == nil ? 'nil' : s.title}.join(',') | |
#end | |
respond_to do |format| | |
format.html # index.html.erb | |
format.js { render :action => 'update' } | |
format.xml { render :xml => @events } | |
end | |
end | |
# GET /events/1 | |
# GET /events/1.xml | |
def show | |
@event = Event.find(params[:id]) | |
respond_to do |format| | |
format.html # show.html.erb | |
format.js | |
format.xml { render :xml => @event } | |
end | |
end | |
# GET /events/new | |
# GET /events/new.xml | |
def new | |
@event = Event.new | |
respond_to do |format| | |
format.html # new.html.erb | |
format.xml { render :xml => @event } | |
end | |
end | |
# GET /events/1/edit | |
def edit | |
@event = Event.find(params[:id]) | |
respond_to do |format| | |
format.js | |
format.xml { render :xml => @event } | |
end | |
end | |
# POST /events | |
# POST /events.xml | |
def create | |
@event = Event.new(params[:event]) | |
respond_to do |format| | |
if @event.save | |
flash[:notice] = 'Event was successfully created.' | |
format.html { redirect_to(events_url) } | |
format.js { render :text => '' } | |
format.xml { render :xml => @event, :status => :created, :location => @event } | |
else | |
format.html { render :action => "new" } | |
format.xml { render :xml => @event.errors, :status => :unprocessable_entity } | |
end | |
end | |
end | |
# PUT /events/1 | |
# PUT /events/1.xml | |
def update | |
@event = Event.find(params[:id]) | |
respond_to do |format| | |
if @event.update_attributes(params[:event]) | |
flash[:notice] = 'Event was successfully updated.' | |
format.html { redirect_to(@event) } | |
format.xml { head :ok } | |
else | |
format.html { render :action => "edit" } | |
format.xml { render :xml => @event.errors, :status => :unprocessable_entity } | |
end | |
end | |
end | |
# DELETE /events/1 | |
# DELETE /events/1.xml | |
def destroy | |
@event = Event.find(params[:id]) | |
@event.destroy | |
respond_to do |format| | |
format.html { redirect_to(events_url) } | |
format.xml { head :ok } | |
end | |
end | |
# PUT /events/1/move | |
def move | |
@event = Event.find(params[:id]) | |
new_data = false | |
event_attribs = params[:event] | |
unless event_attribs.nil? | |
new_data = @event.move(params[:event]) and @event.save | |
end | |
respond_to do |format| | |
format.html { redirect_to(events_url) } | |
format.js { | |
if new_data | |
render(:text => 'RebindCalendar(null);') | |
else | |
render(:text => '') | |
end | |
} | |
format.xml { head :ok } | |
end | |
end | |
def grab_events | |
end | |
end | |
# calendars_helper.rb | |
module CalendarsHelper | |
def events_calendar_opts | |
{ :year => @now_date.year, | |
:month => @now_date.month, | |
:style => "red", | |
:first_day_of_week => @first_day_of_week, | |
:event_strips => @event_strips, | |
:start => @strip_start, | |
:event_width => 81, # total width per day (including margins) | |
:event_height => 16, # height | |
:event_margin => 1, # height margin | |
:previous_month_text => link_to('Previous', {:month => @prev_date.month, :year => @prev_date.year}, :id => 'calPrev'), | |
:next_month_text => link_to('Next', {:month => @next_date.month, :year => @next_date.year}, :id => 'calNext') } | |
end | |
def events_calendar | |
calendar events_calendar_opts do |event, days, cur_offs, idx| | |
"<div evtid=\"#{event.id}\" day=\"#{event.start_date.day}\" class=\"event\" style=\"background: #{event.color}; width: #{(81*days)-1}px; top: #{idx*18}px; left:#{cur_offs}px; \"><div>#{h(event.title)}</div></div>" | |
end | |
end | |
# Returns an HTML calendar. In its simplest form, this method generates a plain | |
# calendar (which can then be customized using CSS). | |
# However, this may be customized in a variety of ways -- changing the default CSS | |
# classes, generating the individual day entries yourself, and so on. | |
# | |
# The following are optional, available for customizing the default behaviour: | |
# :month => Time.now.month # The month to show the calendar for. Defaults to current month. | |
# :year => Time.now.year # The year to show the calendar for. Defaults to current year. | |
# :table_class => "calendar" # The class for the <table> tag. | |
# :month_name_class => "monthName" # The class for the name of the month, at the top of the table. | |
# :other_month_class => "otherMonth" # Not implemented yet. | |
# :day_name_class => "dayName" # The class is for the names of the weekdays, at the top. | |
# :day_class => "day" # The class for the individual day number cells. | |
# This may or may not be used if you specify a block (see below). | |
# :abbrev => (0..2) # This option specifies how the day names should be abbreviated. | |
# Use (0..2) for the first three letters, (0..0) for the first, and | |
# (0..-1) for the entire name. | |
# :first_day_of_week => 0 # Renders calendar starting on Sunday. Use 1 for Monday, and so on. | |
# :accessible => true # Turns on accessibility mode. This suffixes dates within the | |
# # calendar that are outside the range defined in the <caption> with | |
# # <span class="hidden"> MonthName</span> | |
# # Defaults to false. | |
# # You'll need to define an appropriate style in order to make this disappear. | |
# # Choose your own method of hiding content appropriately. | |
# | |
# :show_today => false # Highlights today on the calendar using the CSS class 'today'. | |
# # Defaults to true. | |
# :month_name_text => nil # Displayed center in header row. Defaults to current month name from Date::MONTHNAMES hash. | |
# :previous_month_text => nil # Displayed left of the month name if set | |
# :next_month_text => nil # Displayed right of the month name if set | |
# | |
# For more customization, you can pass a code block to this method, that will get one argument, a Date object, | |
# and return a values for the individual table cells. The block can return an array, [cell_text, cell_attrs], | |
# cell_text being the text that is displayed and cell_attrs a hash containing the attributes for the <td> tag | |
# (this can be used to change the <td>'s class for customization with CSS). | |
# This block can also return the cell_text only, in which case the <td>'s class defaults to the value given in | |
# +:day_class+. If the block returns nil, the default options are used. | |
# | |
# Example usage: | |
# calendar # This generates the simplest possible calendar with the curent month and year. | |
# calendar({:year => 2005, :month => 6}) # This generates a calendar for June 2005. | |
# calendar({:table_class => "calendar_helper"}) # This generates a calendar, as | |
# # before, but the <table>'s class | |
# # is set to "calendar_helper". | |
# calendar(:abbrev => (0..-1)) # This generates a simple calendar but shows the | |
# # entire day name ("Sunday", "Monday", etc.) instead | |
# # of only the first three letters. | |
# calendar do |d| # This generates a simple calendar, but gives special days | |
# if listOfSpecialDays.include?(d) # (days that are in the array listOfSpecialDays) one CSS class, | |
# [d.mday, {:class => "specialDay"}] # "specialDay", and gives the rest of the days another CSS class, | |
# else # "normalDay". You can also use this highlight today differently | |
# [d.mday, {:class => "normalDay"}] # from the rest of the days, etc. | |
# end | |
# end | |
# | |
# An additional 'weekend' class is applied to weekend days. | |
# | |
# For consistency with the themes provided in the calendar_styles generator, use "specialDay" as the CSS class for marked days. | |
# | |
def calendar(options = {}, &block) | |
block ||= Proc.new {|d| nil} | |
defaults = { | |
:year => Time.now.year, | |
:month => Time.now.month, | |
:table_class => 'calendar', | |
:month_name_class => 'monthName', | |
:other_month_class => 'otherMonth', | |
:day_name_class => 'dayName', | |
:day_class => 'day', | |
:abbrev => (0..2), | |
:first_day_of_week => 0, | |
:accessible => false, | |
:show_today => true, | |
:previous_month_text => nil, | |
:next_month_text => nil, | |
:start => nil, | |
:event_strips => nil, | |
:event_width => 81, | |
:event_height => 24, | |
:event_margin => 2 | |
} | |
options = defaults.merge options | |
options[:month_name_text] ||= Date::MONTHNAMES[options[:month]] | |
first = Date.civil(options[:year], options[:month], 1) | |
last = Date.civil(options[:year], options[:month], -1) | |
start = options[:start] | |
event_strips = options[:event_strips] | |
event_width = options[:event_width] | |
event_height = options[:event_height] | |
event_margin = options[:event_margin] | |
first_weekday = first_day_of_week(options[:first_day_of_week]) | |
last_weekday = last_day_of_week(options[:first_day_of_week]) | |
day_names = Date::DAYNAMES.dup | |
first_weekday.times do | |
day_names.push(day_names.shift) | |
end | |
# TODO Use some kind of builder instead of straight HTML | |
cal = %(<table class="#{options[:table_class]}" border="0" cellspacing="0" cellpadding="0">) | |
cal << %(<thead><tr>) | |
if options[:previous_month_text] or options[:next_month_text] | |
cal << %(<th colspan="2">#{options[:previous_month_text]}</th>) | |
colspan=3 | |
else | |
colspan=7 | |
end | |
cal << %(<th colspan="#{colspan}" class="#{options[:month_name_class]}">#{options[:month_name_text]}</th>) | |
cal << %(<th colspan="2">#{options[:next_month_text]}</th>) if options[:next_month_text] | |
cal << %(</tr><tr class="#{options[:day_name_class]}">) | |
day_names.each do |d| | |
unless d[options[:abbrev]].eql? d | |
cal << "<th scope='col'><abbr title='#{d}'>#{d[options[:abbrev]]}</abbr></th>" | |
else | |
cal << "<th scope='col'>#{d[options[:abbrev]]}</th>" | |
end | |
end | |
cal << "</tr></thead><tbody><tr>" | |
beginning_of_week(first, first_weekday).upto(first - 1) do |d| | |
cal << %(<td class="#{options[:other_month_class]}) | |
cal << " weekendDay" if weekend?(d) | |
if options[:accessible] | |
cal << %(">#{d.day}<span class="hidden"> #{Date::MONTHNAMES[d.month]}</span></td>) | |
else | |
cal << %(">#{d.day}</td>) | |
end | |
end unless first.wday == first_weekday | |
start_row = beginning_of_week(first, first_weekday) | |
last_row = start_row | |
first.upto(last) do |cur| | |
cell_text, cell_attrs = nil#block.call(cur) | |
cell_text ||= cur.mday | |
cell_attrs ||= {:class => options[:day_class]} | |
cell_attrs[:class] += " weekendDay" if [0, 6].include?(cur.wday) | |
cell_attrs[:class] += " today" if (cur == Date.today) and options[:show_today] | |
cell_attrs = cell_attrs.map {|k, v| %(#{k}="#{v}") }.join(" ") | |
cal << "<td #{cell_attrs}>#{cell_text}</td>" | |
if cur.wday == last_weekday | |
content = calendar_row(event_strips, | |
event_width, | |
event_height, | |
start_row, | |
last_row..cur, | |
&block) | |
cal << "</tr>#{event_row(content, event_height, event_margin)}<tr>" | |
last_row = cur + 1 | |
end | |
end | |
(last + 1).upto(beginning_of_week(last + 7, first_weekday) - 1) do |d| | |
cal << %(<td class="#{options[:other_month_class]}) | |
cal << " weekendDay" if weekend?(d) | |
if options[:accessible] | |
cal << %(">#{d.day}<span class='hidden'> #{Date::MONTHNAMES[d.mon]}</span></td>) | |
else | |
cal << %(">#{d.day}</td>) | |
end | |
end unless last.wday == last_weekday | |
content = calendar_row(event_strips, | |
event_width, | |
event_height, | |
start_row, | |
last_row..(beginning_of_week(last + 7, first_weekday) - 1), | |
&block) | |
cal << "</tr>#{event_row(content, event_height, event_margin)}</tbody></table>" | |
end | |
private | |
def calendar_row(event_strips, event_width, event_height, start, date_range, &block) | |
start_date = date_range.first | |
range = ((date_range.first - start).to_i)...((date_range.last - start + 1).to_i) | |
idx = -1 | |
#print "ROW: #{date_range} [#{start}] == #{range}\n" | |
last_offs = 0 | |
event_strips.collect do |strip| | |
idx += 1 | |
range.collect do |r| | |
event = strip[r] | |
if !event.nil? | |
# Clip event dates (if it extends before or beyond the row) | |
dates = event.clip_range(start_date, date_range.last) | |
if dates[0] - start_date == r-range.first | |
# Event somewhere on this row | |
cur_offs = (event_width*(r-range.first)) | |
start_d = event.start_date.to_date | |
end_d = event.end_date.nil? ? start_d+1 : event.end_date.to_date+1 | |
block.call(event, dates[1]-dates[0], cur_offs, idx) | |
else | |
nil | |
end | |
else | |
nil | |
end | |
end.compact | |
end | |
end | |
def event_row(content, height, margin) | |
"<tr><td colspan=\"7\"><div class=\"events\" style=\"height:#{(height+margin)*content.length}px\">#{content.join}</div><div class=\"clear\"></div></td></tr>" | |
end | |
def first_day_of_week(day) | |
day | |
end | |
def last_day_of_week(day) | |
if day > 0 | |
day - 1 | |
else | |
6 | |
end | |
end | |
def days_between(first, second) | |
if first > second | |
second + (7 - first) | |
else | |
second - first | |
end | |
end | |
def beginning_of_week(date, start = 1) | |
days_to_beg = days_between(start, date.wday) | |
date - days_to_beg | |
end | |
def weekend?(date) | |
[0, 6].include?(date.wday) | |
end | |
end | |
# event.rb | |
class Event < ActiveRecord::Base | |
belongs_to :calendar | |
belongs_to :created_by, :class_name => 'User', :foreign_key => 'created_by_id' | |
belongs_to :updated_by, :class_name => 'User', :foreign_key => 'updated_by_id' | |
@@repeat_lookup = {:never => 0, :yearly => 1, :monthly => 2, :fortnightly => 3, :weekly => 4, :daily => 5} | |
@@repeat_id_lookup = @@repeat_lookup.invert | |
after_create :process_create | |
before_update :process_update_params | |
before_destroy :process_destroy | |
def process_create | |
ApplicationLog.new_log(self, self.created_by, :add) | |
end | |
def process_update_params | |
ApplicationLog.new_log(self, self.updated_by, :edit) | |
end | |
def process_destroy | |
ApplicationLog.new_log(self, self.updated_by, :delete) | |
end | |
def page | |
nil | |
end | |
def year | |
date.year | |
end | |
def month | |
date.month | |
end | |
def day | |
date.day | |
end | |
def to_date | |
(end_date || start_date).to_date + 1 | |
end | |
def color | |
calendar.color || '#FF0000' | |
end | |
def days | |
to_date.to_date - start_date.to_date | |
end | |
def clip_range(start_d, end_d) | |
# Clip start date | |
if (start_date < start_d and to_date > start_d) | |
clipped_start = start_d | |
else | |
clipped_start = start_date.to_date | |
end | |
# Clip end date | |
if (to_date >= end_d) | |
clipped_end = end_d + 1 | |
else | |
clipped_end = to_date | |
end | |
[clipped_start, clipped_end] | |
end | |
def move(options) | |
new_date = self.start_date | |
# Calculate new date | |
nyear = options.has_key?(:year) ? options[:year].to_i : new_date.year | |
nmonth = options.has_key?(:month) ? options[:month].to_i : new_date.month | |
nday = options.has_key?(:day) ? options[:day].to_i : new_date.day | |
nhour = options.has_key?(:hour) ? options[:hour].to_i : new_date.hour | |
new_date = Time.zone.local(nyear, nmonth, nday, nhour, new_date.min, new_date.sec) | |
delta = new_date - start_date | |
if delta == 0 | |
return false | |
end | |
new_end = self.end_date | |
unless new_end.nil? | |
# Need to increment end date by delta | |
delta = new_date - self.start_date | |
self.start_date = new_date | |
self.end_date = new_end + delta | |
else | |
# Just set the new date | |
self.start_date = new_date | |
end | |
return true | |
end | |
def object_name | |
self.content | |
end | |
def friendly_at_time | |
@cached_friendly_time || self.at_time.to_s | |
end | |
def friendly_at_time=(value) | |
@cached_friendly_time = value | |
times = Chronic.parse(value, :now => Time.zone.now, :guess => false) | |
# TODO: possible to extract subject from query? | |
start_time = nil | |
end_time = nil | |
if !times.nil? | |
if times.class == Chronic::Span | |
start_time = times.begin | |
end_time = times.end-1 | |
else | |
start_time = times | |
end | |
# re-interpret | |
start_time = Time.zone.local(start_time.year, start_time.mon, start_time.day, start_time.hour, start_time.min, start_time.sec) | |
unless end_time.nil? | |
end_time = Time.zone.local(end_time.year, end_time.mon, end_time.day, end_time.hour, end_time.min, end_time.sec) | |
end | |
else | |
# Default to now + 3 hours | |
start_time = (Time.zone.now + (60*60*3)) | |
end | |
self.start_date = start_time | |
self.end_date = end_time | |
self.title = value | |
end | |
def friendly_repeat | |
"reminder_repeat_#{self.repeat}".to_sym.l | |
end | |
def repeat | |
@@repeat_id_lookup[self.repeat_id] | |
end | |
def repeat=(val) | |
self.repeat_id = @@repeat_lookup[val.to_sym] | |
end | |
def done? | |
expires_at <= Time.zone.now | |
end | |
def repeatable? | |
self.repeat_id > 0 | |
end | |
def expires_at | |
self.end_date || self.start_date | |
end | |
# Common permissions | |
def self.can_be_created_by(user) | |
user.member_of_owner? | |
end | |
def can_be_edited_by(user) | |
return (user.is_admin or user.id == self.created_by_id) | |
end | |
def can_be_deleted_by(user) | |
return (user.is_admin or user.id == self.created_by_id) | |
end | |
def can_be_seen_by(user) | |
return (user.is_admin or self.created_by_id == user.id) | |
end | |
def self.select_repeat | |
@@repeat_lookup.keys.map do |key| | |
["reminder_repeat_#{key}".to_sym.l, key] | |
end | |
end | |
# Accesibility | |
attr_accessible :repeat, :friendly_at_time, :title, :description, :at_time, :calendar_id | |
# Validation | |
validates_presence_of :title | |
end | |
# calendar.rb | |
class Calendar < ActiveRecord::Base | |
belongs_to :created_by, :class_name => 'User', :foreign_key => 'created_by_id' | |
belongs_to :updated_by, :class_name => 'User', :foreign_key => 'updated_by_id' | |
has_many :application_logs, :as => :rel_object#, :dependent => :nullify | |
has_many :events | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment