新手问题 ActiveRecord 求救??

feipinghuang · 2012年11月05日 · 最后由 jimrokliu 回复于 2012年11月07日 · 3450 次阅读

class Message < ActiveRecord::Base belongs_to :user end

class MessageRecipient < ActiveRecord::Base belongs_to :message belongs_to :message_recipientable, polymorphic: true end

class User < ActiveRecord::Base has_many :message_recipients, as: :message_recipientable has_many :messages, through: :message_recipients, source: :message end

class Group < ActiveRecord::Base has_many :message_recipients, as: :message_recipientable has_many :messages, through: :message_recipients, source: :message end

我要做的是类似 QQ 的聊天应用,有群聊和单聊

我的现在遇到的问题是:在不写纯 SQL 的情况下,怎么一次操作拿到单聊的两个人的 messages

如拿 user1 和 user2 的 messages

user1.massages.where user_id: user2.id //user2 发给 user1 的 mesaage

user2.massages.where user_id: user1.id //user1 发给 user2 的 mesaage

怎么样整合这两句???

Message.where(user_id: [user1.id, user2.id])

#1 楼 @tumayun 我要查的是两个人的对话,不是查他们两各自发过的 message

@feipinghuang 你需要一个 thread 一类的 model 不然你每次取会取回 两个人有史以来所有的 messages

可以使用 xmpp 啊

我之前的做法是两个人各保存一份完整的对话记录

#3 楼 @knwang 请问这个 thread 需要哪些字段

#6 楼 @feipinghuang 看你的义务需求了,但至少可以有

has_many :messages

是缺少一个 thread 对象,还可以 belong_to :group,group 是群聊组。

或者 Messagesender_idreceiver_id

# coding: utf-8
class Message
  include Mongoid::Document
  include Mongoid::Timestamps::Created  
  include Mongoid::CounterCache
  include Mongoid::DelayedDocument

  field :content
  field :sender_id
  field :receiver_id
  field :readed, :type => Boolean, :default => false

  embedded_in :dialog
  counter_cache :name => :dialog, :inverse_of => :messages

  belongs_to :sender, :class_name => 'User', :foreign_key => 'sender_id'
  belongs_to :receiver, :class_name => 'User', :foreign_key => 'receiver_id'

  validates :content, :presence => true, :length => { :maximum => 140 }

  index :receiver_id => 1
  index :created_at => -1

  default_scope desc('created_at')

  # A little confused.
  def self.post(sender_id, receiver_id, content)
    return if sender_id == receiver_id
    other_dialog = Dialog.find_or_create_by(:from_user_id => receiver_id, :to_user_id => sender_id)
    params = { :content => content, :sender_id => sender_id, :receiver_id => receiver_id }
    other_dialog.messages.create(params)
    self.perform_async(:send_message_to_self, params)
  end

  def self.send_message_to_self(opts)
    self_dialog = Dialog.find_or_create_by(:from_user_id => opts['sender_id'], :to_user_id => opts['receiver_id'])
    self_dialog.messages.create(opts)
    User.where(:_id => opts['receiver_id']).first.inc(:messages_count, 1)    
  end

  after_create do
    self.dialog.update_attributes(
      :last_reply_user_id       => self.sender_id,
      :last_reply_user_login    => self.sender.login,
      :last_reply_content       => self.content,
      :updated_at               => self.created_at
    )


  end

end

A 和 B 聊天。 message 上面应该有 sender 和 receiver 吧。 (sender==a and receiver==b) || (sender==b and receiver=a)

关系好像有点那个了

#8 楼 @jimrokliu 能贴一个简单的 thread 例子吗 不太明白它是来干嘛的

#10 楼 @fresh_fish 非常感谢

#12 楼 @woaigithub MessageRecipient 模型就是 receiver

当你说去处 a 和 b 的会话,或者问 a 同其他用户存在会话?那么在概念模型上就需要一个 Thread 概念,Thread 代表了一次会话,通常有相同讨论上下文,有发起人,结束时间。参与人。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号