【问题标题】:Preferred way to private messages modeling in Rails 3在 Rails 3 中进行私人消息建模的首选方式
【发布时间】:2011-07-05 01:53:09
【问题描述】:

我计划在成员之间实施私人消息系统。我想知道对此的首选方法是什么。

要求是

  1. 我应该能够像这样轻松地检索它们

    @user.conversations               #Should return User objects that I sent or received messages from (but not me)
    @user.conversations.messages      #Messages from all or specific user objects.
    @user.conversations.messages.unread      #Unread messages
    
  2. 调用@user.conversations 时,应仅检索向我发送消息的人或我向其发送消息的人。 current_user 应该被排除在外。

  3. 如果我是 sender_id=5 并且发送 to_id=10,那么其他人将回复为 sender=10 to_id=5。这应该被认为和理解为同一个会话对象。


关于最后一点。我不确定首选的建模方法是什么。

最好使用一种对话模型来处理所有消息,例如

    attr_accessible :user_id, :friend_id, :message, :read
    belongs_to :user

或者最好创建一个对话模型来处理关联和一个消息模型。

我想看看如何实现这种关系的示例案例,以及是否有其他方法可以实现。

我有点迷路了。

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-3


    【解决方案1】:

    如果您使用此数据库模型:

    User id:integer ....
    
    Message id:integer body:string
    
    UserMessages id:integre sender_id:integer to_id:integer message_id
    

    我猜你需要在 :has_many 中提供 :finder_sql,类似这样的东西

    class User < ActiveRecord::Base
       has_many :conversations, :class_name => "UserMessage", :finder_sql =>
          'SELECT * ' +
          'FROM user_messages' +
          'WHERE sender_id = #{id} OR to_id = #{id} ' 
    
    end
    

    【讨论】:

    • 您也可以使用 .column_names["attr_accessible"].name 作为您想要的数据库列名和 .table_name 以避免命名问题
    【解决方案2】:

    一个更简单的模型是捕获每条消息:

    class Message < ActiveRecord::Base
      belongs_to :from_user,  :class_name => 'User' # from_user_id field fk Users
      belongs_to :to_user,    :class_name => 'User' # to_user_id field fk Users
      belongs_to :thread, :class_name => 'Message'  # Reference to parent message
      has_many :replies,  :class_name => 'Message', :foreign_key => 'thread_id'
    
      named_scope :in_reply_to, lambda { |message| :conditions => {:thread => message}, :order => 'created_at' }
    end
    
    class User < ActiveRecord::Base
      has_many :messages_received,  :class_name => 'Message', :foreign_key=> 'to_user_id'
      has_many :messages_sent,      :class_name => 'Message', :foreign_key=> 'from_user_id'
    end
    

    如果您需要捕获消息线程,任何作为回复的消息都可以存储对开始对话(又名线程)的初始消息的引用。例如:

    first_msg   = Message.new(:to_user => bob, :from_user => sally, :body => 'Hello!')
    sally_reply = first_msg.replies.build(:to_user => bob, :from_user => sally, :body => 'hi back')
    bob_reply   = first_msg.replies.build(:to_user => sally, :from_user => bob, :body => 'later')
    

    【讨论】:

    • @Winfield 如何使用 in_reply_to 获取根文档?我想要类似 twitter DM 的东西
    • 根消息的 in_reply_to 值为空。
    • @Winfield 谢谢,我通过添加 before_create 过滤器解决了这个问题,将 thread_id 添加为 message_id,以防没有提供 thread_id。这将返回所有文档,包括主要文档。
    【解决方案3】:

    如果是你,我会使用 IMAP 而不是使用数据库进行此类建模。

    查看this了解更多详情。

    【讨论】:

      【解决方案4】:

      acts_as_messageable 有点长,但应该能给你一些想法。

      【讨论】:

      • 我更喜欢这个,因为那里有很多 act_as_* 插件/宝石。根据@Martin 上面提到的要求,它符合他的需求。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-22
      相关资源
      最近更新 更多