Skip to main content

How do I structure a Conversation between two models?

Rails • Asked by Taylor Cooney

I have a Store object that has an email_address attribute. Using the logic from and How To Build A Form and Handling Inbound Email Parsing with Rails, I'm trying to figure out how to structure a Conversation where a visitor can email the Store, and the Store can reply through email - their replies would post messages to the Conversation.

When a visitor inquires to the store (via form), I create a Reservation record with their name and email, and start a Conversation like this,
@conversation = Conversation.create(sender_id: self.id, recipient_id: self.store_id)

I wanted to model the notifications similar to this, where everyone but the sender receives an email, but I'm stumped on how to map the User, since it's two different objects (Reservation and Store):

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

The Conversation model looks like this, may be wrong, any guidance on what I could use to make the messages unique and structure the notifications?

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

The Message Post isn't fully fleshed out, not sure what to use to make it unique between the two Objects.

class Message < ApplicationRecord
  belongs_to :conversation
  validates_presence_of :body, :conversation_id

  def send_notifications!

  end
end

Talor, would you mind posting the message model as well?


Just updated the bottom of the thread Casey; needing some guidance on setting up the Conversation and Message between two different models.


My assumption: A conversation is only between 2 people

So I think one thing that would make this easier to by putter an author_id on a message. This way you know who composed and sent the message. If you do this then you can just send a notification on the after_create callback of the Message model. In that callback I would do something like.

def after_create
  UserMailer.new_message(self.id).deliver_later
end

class UserMailer
  def new_message(message_id)
        message = Message.includes(conversation: [:sender, :recipient]).find(message_id)
        recipient = message.conversation.sender_id == message.author_id ? message.conversation.recipient : message.conversation.sender
        mail(to: recipient.email)
    end
end

What does your code like that receives and parses the email?


I haven't written the portion to parse the email and create the post, but I planned to model it around the logic here, Handling Inbound Email Parsing with Rails


I didn't realize I could access conversation.recipient and conversation.sender so easily, going to try to model it as you suggested above Casey :thumbs_up:


Login or Create An Account to join the conversation.

Subscribe to the newsletter

Join 24,647+ developers who get early access to new screencasts, articles, guides, updates, and more.

    By clicking this button, you agree to the GoRails Terms of Service and Privacy Policy.

    More of a social being? We're also on Twitter and YouTube.