Skip to content

Instantly share code, notes, and snippets.

@codesnik
Created March 5, 2010 21:34
Show Gist options
  • Save codesnik/323179 to your computer and use it in GitHub Desktop.
Save codesnik/323179 to your computer and use it in GitHub Desktop.
class Message
include DataMapper::Resource
property :id, Serial
property :subject, String
property :body, Text
property :unread, Boolean, :default => true, :required => true
property :created_at, DateTime
property :updated_at, DateTime
## обновляет updated_at у родительского сообщения, нужно для сортировки
belongs_to :parent, "Message", :required => false # :touch => true
belongs_to :sender, "User"
belongs_to :recipient, "User"
has n, :messages, :child_key => [:parent_id] # :dependent => :delete_all
def self.ordered_by_creation; all(:order => [:created_at.desc]) end
def self.threads; all(:parent => nil) end
def self.unread; all(:unread => true) end
def self.with_user user
# all(:conditions => ["recipient_id = ? or sender_id = ?", user.id, user.id])
all(:recipient => user) + all(:sender => user)
end
def self.written_by user; all(:sender => user) end
def self.received_by user; all(:recipient => user) end
def self.unread_by user; unread.received_by(user) end
def self.ordered_by_activity; all(:order => [:updated_at.desc]) end
## что-то одно должно присутствовать
#validates_presence_of :body, :if => proc {|msg| msg.subject.blank? }
def thread_starter?; !parent end
def reply?; !thread_starter? end
def thread; parent || self end
#def thread_id; parent_id || id end
## TODO try to get this via association
def thread_messages
Message.all(:conditions => ["id = ? or parent_id = ?", thread.id, thread.id]).ordered_by_creation
end
def thread_messages_count
thread.messages.count + 1
end
def new_reply(author)
msg = thread.messages.new :sender => author
# можно писать в свой же тред
msg.recipient = (thread.sender == author) ? thread.recipient : thread.sender
msg
end
delegate :subject, :to => :thread, :prefix => :thread
def unread_by?(reader)
unread? && reader != sender
end
def unread_count_for(reader)
thread_messages.unread_by(reader).count
end
def thread_unread_by?(reader)
unread_count_for(reader) != 0
end
def first_unread_or_last_read_for(reader)
thread_messages.unread_by(reader).first || thread_messages.last
end
def read!(reader)
thread_messages.unread_by(reader).update! :unread => false
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment