app/models/task.rb
class Task
include Mongoid::Document
include Mongoid::Timestamps
#include Mongoid::History::Trackable
include ActiveModel::MassAssignmentSecurity
include Model::MongoDb::Customizable
include Model::MongoDb::Commentable
include StateMachines::Task
belongs_to :story
belongs_to :result
accepts_nested_attributes_for :result, allow_destroy: true
field :offeror_id, type: Integer
field :user_id, type: Integer
field :author_id, type: Integer
field :name, type: String
field :text, type: String
field :state, type: String
field :unassigned_user_ids, type: Array
attr_accessible :story, :story_id, :name, :text, :result_attributes
scope :current, -> { where(state: 'new') }
scope :unassigned, -> { where(user_id: nil) }
scope :assigned, -> { ne(user_id: nil) }
scope :complete, -> { where(state: 'completed') }
scope :incomplete, -> { ne(state: 'completed') }
validates :story_id, presence: true
validates :offeror_id, presence: true, if: 'story_id.present? && (story rescue nil) && story.with_offeror'
validates :text, presence: true, if: ->(t) { t.class.name == 'Task' }
validate :name_valid?
after_initialize :cache_associations
before_validation :cache_associations
after_destroy :destroy_result
#track_history on: [:user_id, :name, :text, :state]
PARENT_TYPES = ['story']
# belongs_to (SQL)
def offeror; offeror_id ? User.find(offeror_id) : nil; end
def offeror=(value); self.offeror_id = value.id; end
def user; user_id ? User.find(user_id) : nil; end
def user=(value); self.user_id = value.id; end
def author; author_id ? User.find(author_id) : nil; end
def author=(value); self.author_id = value.id; end
def result_class
if product_id.present?
"#{product.class.name}::Result".constantize rescue Result
else
Result
end
end
def with_result?
true
end
def before_transition(transition)
self.event = transition.event.to_s
self.state_before = transition.from
case transition.event
when :assign
self.author_id = self.user_id
when :cancel
self.unassigned_user_ids ||= []
self.unassigned_user_ids << self.user_id
self.user_id = nil
self.author_id = nil
self.result.text = nil if self.result
when :review
self.user_id = self.offeror_id
when :follow_up
self.user_id = self.author_id
end
end
def after_transition(transition)
case transition.event
when :follow_up
self.story.activate if self.story.completed?
when :complete
if self.story.tasks.complete.count == self.story.tasks.count
self.story.complete
end
end
end
def to_json
record = {
id: id.to_s, offeror_id: offeror_id, user_id: user_id, author_id: author_id, name: name, text: text, state: state
}
record[:result] = result.to_json if result.present?
record
end
protected
# validates :name, presence: true, uniqueness: { scope: :story_id }
def name_valid?
return unless name_changed?
if name.present?
if Task.where(name: name, story_id: story_id).any?
errors.add(:name, I18n.t('errors.messages.taken'))
end
else
errors.add(:name, I18n.t('errors.messages.blank'))
end
end
private
def destroy_result
if respond_to? :results
results.map(&:destroy)
else
result.try(:destroy)
end
end
def cache_associations
self.offeror_id = story.offeror_id if story_id.present? && (story rescue nil) && story.with_offeror
end
def cache_product_association
self.product_id = story.product_id if story_id.present? && (story rescue nil)
end
end