Я собираю систему сообщений для приложения rails, над которым я работаю.
Я создаю его аналогично системе Facebook, поэтому сообщения сгруппированы в темы и т. Д.
Мои родственные модели:
- MsgThread - главный контейнер нити
- Сообщение - каждое сообщение / ответ в теме
- Recipience - связывается с пользователем, чтобы определить, какие пользователи должны подписаться на эту тему
- Чтение - определяет, прочитал ли пользователь конкретное сообщение
Мои отношения выглядят как
class User < ActiveRecord::Base
#stuff...
has_many :msg_threads, :foreign_key => 'originator_id' #threads the user has started
has_many :recipiences
has_many :subscribed_threads, :through => :recipiences, :source => :msg_thread #threads the user is subscribed to
end
class MsgThread < ActiveRecord::Base
has_many :messages
has_many :recipiences
belongs_to :originator, :class_name => "User", :foreign_key => "originator_id"
end
class Recipience < ActiveRecord::Base
belongs_to :user
belongs_to :msg_thread
end
class Message < ActiveRecord::Base
belongs_to :msg_thread
belongs_to :author, :class_name => "User", :foreign_key => "author_id"
end
class Read < ActiveRecord::Base
belongs_to :user
belongs_to :message
end
Я бы хотел создать новый селектор в пользовательском виде вроде:
has_many :updated_threads, :through => :recipiencies, :source => :msg_thread, :conditions => {THREAD CONTAINS MESSAGES WHICH ARE UNREAD (have no 'read' models tying a user to a message)}
Я думал о том, чтобы либо написать длинное условие с несколькими объединениями, либо, возможно, написать, чтобы дать модели метод updated_threads, чтобы вернуть это, но я хотел бы посмотреть, есть ли более простой способ в первую очередь. Могу ли я передать какой-то вложенный хеш в условия вместо строки?
Есть идеи? Также, если с моей структурой что-то не так для этой функции, дайте мне знать! Спасибо !!
UPDATE:
В то время как я все еще буду благодарен за информацию о лучших возможностях, если они существуют, сейчас я начал работать над этим:
class User < ActiveRecord::Base
# stuff...
def updated_threads
MsgThread.find_by_sql("
SELECT msg_threads.* FROM msg_threads
INNER JOIN messages ON messages.msg_thread_id = msg_threads.id
INNER JOIN recipiences ON recipiences.msg_thread_id = msg_threads.id
WHERE (SELECT COUNT(*) FROM `reads` WHERE reads.message_id = messages.id AND reads.user_id = #{self.id}) = 0
AND (SELECT COUNT(*) FROM recipiences WHERE recipiences.user_id = #{self.id} AND recipiences.msg_thread_id = msg_threads.id) > 0
")
end
end
Кажется, работает нормально!
Также, чтобы проверить, читается ли конкретная тема (и сообщение):
class Message < ActiveRecord::Base
# stuff...
def read?(user_id)
Read.exists?(:user_id => user_id, :message_id => self.id)
end
end
class MsgThread < ActiveRecord::Base
# stuff...
def updated?(user_id)
updated = false
self.messages.each { |m| updated = true if !m.read?(user_id) }
updated
end
end
Любые предложения по улучшению этого?