tracks/app/models/project.rb
Reinier Balt 5ed69fc1a2 update gems and fix failures from new aasm
I'm not sure the test failures caused by reload not working are caused by the new aasm, 
perhaps the thread isolation is causing that...
2013-04-29 11:53:32 +02:00

172 lines
4.1 KiB
Ruby

class Project < ActiveRecord::Base
has_many :todos, :dependent => :delete_all, :order => 'todos.due IS NULL, todos.due ASC, todos.created_at ASC'
has_many :notes, :dependent => :delete_all, :order => "created_at DESC"
has_many :recurring_todos
belongs_to :default_context, :class_name => "Context", :foreign_key => "default_context_id"
belongs_to :user
scope :active, :conditions => { :state => 'active' }
scope :hidden, :conditions => { :state => 'hidden' }
scope :completed, :conditions => { :state => 'completed'}
scope :uncompleted, :conditions => ["NOT(state = ?)", 'completed']
scope :with_name_or_description, lambda { |body| where("name LIKE ? OR description LIKE ?", body, body) }
validates_presence_of :name
validates_length_of :name, :maximum => 255
validates_uniqueness_of :name, :scope => "user_id"
acts_as_list :scope => 'user_id = #{user_id} AND state = \'#{state}\'', :top_of_list => 0
include AASM
aasm :column => :state do
state :active, :initial => true
state :hidden, :enter => :hide_todos, :exit => :unhide_todos
state :completed, :enter => :set_completed_at_date, :exit => :clear_completed_at_date
event :activate do
transitions :to => :active, :from => [:active, :hidden, :completed]
end
event :hide do
transitions :to => :hidden, :from => [:active, :completed]
end
event :complete do
transitions :to => :completed, :from => [:active, :hidden]
end
end
attr_protected :user
attr_accessor :cached_note_count
def self.null_object
NullProject.new
end
def self.create_from_todo(todo)
project = Project.new(:name => todo.description,
:description => todo.notes,
:default_context => todo.context)
project.user = todo.user
if project.valid?
todo.destroy
project.save!
end
project
end
def hide_todos
todos.each do |t|
unless t.completed? || t.deferred?
t.hide!
t.save
end
end
end
def unhide_todos
todos.each do |t|
if t.project_hidden?
t.unhide!
t.save
end
end
end
def set_completed_at_date
self.completed_at = Time.zone.now
end
def clear_completed_at_date
self.completed_at = nil
end
def note_count
# TODO: test this for eager and not eager loading!!!
return 0 if notes.size == 0
cached_note_count || notes.count
end
alias_method :original_default_context, :default_context
def default_context
original_default_context.nil? ? Context.null_object : original_default_context
end
# would prefer to call this method state=(), but that causes an endless loop
# as a result of acts_as_state_machine calling state=() to update the attribute
def transition_to(candidate_state)
case candidate_state.to_sym
when aasm_current_state
return
when :hidden
hide!
when :active
activate!
when :completed
complete!
end
end
def needs_review?(current_user)
return active? && ( last_reviewed.nil? ||
(last_reviewed < current_user.time - current_user.prefs.review_period.days))
end
def blocked?
## mutually exclusive for stalled and blocked
# blocked is uncompleted project with deferred or pending todos, but no next actions
return false if self.completed?
return !self.todos.deferred_or_blocked.empty? && self.todos.not_deferred_or_blocked.empty?
end
def stalled?
# Stalled projects are active projects with no active next actions
return false if self.completed? || self.hidden?
return self.todos.deferred_or_blocked.empty? && self.todos.active.empty?
end
def shortened_name(length=40)
name.truncate(length, :omission => "...").html_safe
end
def name=(value)
self[:name] = value.gsub(/\s{2,}/, " ").strip
end
def new_record_before_save?
@new_record_before_save
end
def age_in_days
@age_in_days ||= (Date.today - created_at.to_date + 1).to_i
end
end
class NullProject
def hidden?
false
end
def nil?
true
end
def id
nil
end
def name
""
end
end