Как структурировать разговор между двумя моделями? - PullRequest
0 голосов
/ 16 апреля 2019

У меня есть Store объект с атрибутом email_address. Используя логику и Как создать форму и Обработка разбора входящей электронной почты с помощью Rails , я пытаюсь выяснить, как структурировать Conversation, где посетитель может отправить по электронной почте Store, и Store может ответить по электронной почте - их ответы будут отправлять Message на Conversation.

Когда посетитель запрашивает магазин (через форму), я создаю запись Reservation с его именем и адресом электронной почты и начинаю Conversation следующим образом:

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

Я хотел смоделировать уведомления, подобные этим, когда каждый, кроме отправителя, получает электронное письмо, но я озадачен тем, как сопоставить пользователя, поскольку это два разных объекта (Reservation и Store):

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

Модель беседы выглядит следующим образом, может быть ошибочной, какие-либо указания относительно того, что я мог бы использовать, чтобы сделать сообщения уникальными и структурировать уведомления?

class Conversation < ApplicationRecord
  belongs_to :sender, :foreign_key => :sender_id, class_name: "Reservation"
  belongs_to :recipient, :foreign_key => :recipient_id, class_name: "Store"
  belongs_to :reservation

  has_many :messages, dependent: :destroy
end

1 Ответ

1 голос
/ 16 апреля 2019

Самый простой и гибкий способ - установить это как ассоциацию «многие ко многим»:

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 является получателем. При отправке начального сообщения пользователю вы должны отправить POST на /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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...