如何构建两个模型之间的对话?

时间:2019-04-16 14:02:44

标签: ruby-on-rails

我有一个Store对象,该对象具有email_address属性。使用How To Build A FormHandling Inbound Email Parsing with Rails中的逻辑,我试图弄清楚如何构造一个Conversation,以便访客可以通过电子邮件发送Store和{{1 }}可以通过电子邮件回复-他们的回复会将Store发布到Message

当访客(通过表单)查询商店时,我用他们的姓名和电子邮件创建了Conversation记录,并像这样启动Reservation

Conversation

我想要对通知进行类似的建模,除了发件人之外,其他所有人都会收到一封电子邮件,但是由于它是两个不同的对象(预订和存储),我对如何映射用户感到很困惑:

@conversation = Conversation.create(sender_id: self.id, recipient_id: self.store_id)

“对话”模型如下所示,可能是错误的,关于我可以用来使消息唯一并构造通知的任何指导?

def send_notifications!
    (forum_thread.users.uniq - [user]).each do |user|
      UserMailer.new_post(user, self).deliver_now
    end
  end

1 个答案:

答案 0 :(得分:1)

最简单,最灵活的方法是将其设置为多对多关联:

class User < ApplicationRecord
  has_many :messages
  has_many :conversations, through: :messages
end

class Message < ApplicationRecord
  belongs_to :user
  belongs_to :conversation
end

class Conversation < ApplicationRecord
  has_many :messages
  has_many :users, through: :messages
end

这里Message实际上是将其绑在一起的联接表。 Conversion是收件人。向用户发送初始消息时,您将发布到/users/:user_id/messages

<%= form_with(model: [@user, @message || Message.new]) do |f| %>
   # ...
<% end %>

module Users
  class MessagesController < ApplicationController
    # POST /users/:user_id/messages
    def create
      @user = User.find(params[:user_id])
      @conversation = Conversation.joins(:users)
                                  .where(users: { id: [current_user, @user]})
                                  .first_or_create
      @message = @conversation.messages.new(message_params.merge(user: current_user))
      if @message.save 
         redirect_to @coversation
      else 
         render :new
      end
    end
  end
end

然后您将在单独的控制器中处理对话的视图和控制器(例如聊天窗口):

<%= form_with(model: [@conversation, @message || @conversation.messages.new]) do |f| %>
   # ...
<% end %>

module Conversations
  class MessagesController < ApplicationController
    # POST /conversations/:conversation_id/messages
    def create
      @conversation = Conversation.find(params[:conversation_id])
      @message = @conversation.messages.new(message_params.merge(user: current_user))
      if @message.save 
         redirect_to @coversation
      else 
         render :new
      end
    end
  end
end