【问题标题】:Rails 3 - Set a conversation_id for private messagingRails 3 - 为私人消息设置一个 conversation_id
【发布时间】:2013-09-23 05:21:27
【问题描述】:

我正在尝试为我的 Rails 应用程序在用户之间实现一个简单的私人消息传递功能。我认为我的模型(用户和消息)设置正确,可以发送/接收简单的私人消息。但是,现在我想添加一个似乎需要某种线程的回复功能 - 因此,我尝试使用消息表中的 conversation_id 列来跟踪这一点。有人对我如何最初设置对话 ID 有建议吗?然后为后续回复消息重新设置?

非常感谢任何帮助。此外,我认为这对许多希望添加相同功能的新手程序员很有帮助。谢谢。

用户模型

has_many :sent_messages,     :class_name => "Message", :foreign_key => "sender_id"
has_many :received_messages, :class_name => "Message", :foreign_key => "receiver_id"

消息模型

belongs_to :sender,       :class_name => "User"
belongs_to :receiver,     :class_name => "User"  
belongs_to :conversation, :class_name => "Message", :foreign_key => "conversation_id"
has_many   :replies,      :class_name => "Message", :foreign_key => "conversation_id"

after_save :set_conversation_id  #only if nil (see private method below)

private

def set_conversation_id
  if self.conversation_id.nil?
    primary_key = self.id
    self.update_attributes(:conversation_id => primary_key)
  end
end

新消息表单 (messages/new.html.erb)

<%= form_for(@message) do |f| %>
  <%= render 'shared/error_messages', object: f.object %>

  <%= f.hidden_field :receiver_id, { :value => params[:user_id] } %>
  <%= f.hidden_field :sender_id, { :value => params[:sender_id] } %>

  <%= f.label :subject %>
  <%= f.text_field :subject %>

  <%= f.label :body %>
  <%= f.text_area :body %>

  <%= f.submit "Send", class: "btn btn-medium btn-primary" %>
<% end %>

消息控制器

def new
  @message = Message.new
end

def create
  @message = Message.new(params[:message])
 if @message.save
   flash[:success] = "Message sent!"
   redirect_to root_path
 else
   render 'new'
 end
end

【问题讨论】:

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


    【解决方案1】:

    方法一

    从你开始的开始......

    您可以从拥有has_many 消息的Conversation 模型开始。创建新线程时,创建一个新的Conversation 并将其 ID 用于第一条消息。创建消息作为对现有消息的回复时,复制该消息的 conversation_id

    # new conversation
    conv = Conversation.create # parameters ...
    message = conv.messages.build # parameters ...
    
    # reply
    message = origin.conv.messages.build # parameters
    

    但是,这不会跟踪消息的顺序。

    方法二

    我会做什么......

    我会让每条消息都有一个parent_id,这是它要回复的消息的主键。如果消息是“root”,则此字段将为空。在运行时,这可用于派生对话线程。

    class Message
      has_one :child, class_name: 'Message', foreign_key: 'parent_id'
      belongs_to :parent, class_name: 'Message'
      # ...
    

    方法3

    使用或改编自acts_as_messageable

    【讨论】:

    • 吉姆,我要试试你的方法 2(以避免额外的模型)。您如何看待在 Message 模型上运行 after_save 回调以将 conversation_id 设置为等于 primary_key(如果 conversation_id 尚不存在 - 即,对于第一条消息)?我已经更新了上面的代码,以向您展示我的意思。
    • 我不会那样做,除非有明确的记录。 Future-me 可能会在跟踪消息时编写某种无限循环。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-05
    • 1970-01-01
    • 2011-08-20
    • 1970-01-01
    • 2014-02-18
    相关资源
    最近更新 更多