Now that we can see Topics, there’s one last thing that’s missing. We can track replies, but there’s no way to send a reply. Technically, sending a reply should be opposite process as receiving one, so let’s get started!
TLDR: You can find the code in this GitHub repository. Every part has a corresponding commit.
We can start with a button this time. I personally added option to reply to each Message
in a Topic. For that, we add link to a new Message
, but this time, we also pass message_id
so we know to which Message
we want to reply to.
1
<%= link_to 'Reply', new_message_path(reply_to_id: message.id), class: "rounded-lg py-3 px-5 bg-gray-100 inline-block font-medium" %>
Replying to an email is simply reversing from and to. It’s also common to prepend Re: to the original subject.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# ...
def new
@message = Message.new
if params[:reply_to_id].present?
reply_to = Message.find(params[:reply_to_id])
@message.reply_to = reply_to # we also have to save reference to original Message
@message.subject = "Re: #{reply_to.subject}"
@message.to = reply_to.from
@message.from = reply_to.to
@message.cc = reply_to.cc
end
end
# ...
This change prefill new Message
object with all reply related data. We also set reference to Message
this new one is a reply to. As we need the reply_to
value to be part to the HTML form, incidentally being passed in form data to the create
method, we have to do few minor changes.
1
2
<%= form_with(model: message, class: "contents") do |form| %>
<%= form.hidden_field :reply_to_id %>
We have to add new hidden field to the form which will include id of a Message
we are replying to. We also have to allow reply_to_id
as a valid param for a Message
. This we can do by updating existing message_params
method in the MessagesController
.
1
2
3
4
5
6
7
8
9
class MessagesController < ApplicationController
# ...
def message_params
params.require(:message).permit(:subject, :from, :to, :cc, :bcc, :content, :reply_to_id, attachments: [])
end
# ...
end
Right now, if you try to send a new reply, email will be delivered and new Message
record will also include reply_to
association to another Message
. That could be enough, but if you remember from reply tracking part, we tracked replies by reading a message_id
from the Mail
object. It’d be a good idea to also pass message_id
of a Message
we are trying to send a reply to, so we make tracking of replies possible for receiver of the reply too.
1
2
3
4
5
6
7
8
9
class MessageMailer < ApplicationMailer
def send_message(message_id)
# ...
if @message.reply_to.present?
headers['In-Reply-To'] = @message.reply_to.message_id
end
mail subject: ...
And that’s it. This simple change ensures we are including correct header to mark email as a reply to another email.
This part was fairly short and simple, but our app currently looks like a mess unless you did some styling on your own. I won’t include changes in the text, but I’ll add one extra commit with few UX changes and my attempt to styling.
Comments powered by Disqus.