Customizing the Mailboxer Ruby Gem

Update 3/1/2015: This tutorial has been updated for Rails 4.2 and Mailboxer 0.12. I also created a demo application that can be found on Github. A live demo of the app is also available on Heroku.

The Mailboxer Ruby gem is a robust messaging system that is extremely easy to implement in any Rails app. There are some good tutorials out there that explain how to quickly get it up and running but I saw many questions that asked how to customize the inbox. In this blog post I will explain how to set up the Mailboxer gem and customize the views to contain the following:

  • Inbox with Sender, Subject, Date, and link to move to Trash
  • Trash with the same information as Inbox as well as a button to delete all conversations in Trash and a button to move a conversation back to the Inbox
  • Conversation view page showing all associated messages and a reply form

You’ll see the words “conversation” and “message” used throughout this blog post. In Mailboxer a conversation is simply a group of messages. Our Inbox and Trash pages will contain a table of conversations. Clicking on a conversation will open all of the messages associated with that conversation.

Note: I will be using the current_user method to refer to the currently logged in user. This method is supplied by the Devise gem. If you are not using Devise to handle user authentication be sure to replace this method with your own.

Much of this code for the Conversations controller was provided by RKushnir’s Mailboxer sample app on Github. You can see the full controller code here (since this is a private messaging system between two users, the create action in the linked controller is not needed).


Add the following line to your Gemfile:

gem "mailboxer"

Then run:

bundle update

Next, run the install script. This script will automatically create the migrations that are required for Mailboxer to run:

rails g mailboxer:install

Migrate your database once the installation is complete:

rake db:migrate

Prepare the models

Mailboxer can be used on any model but in this example we’ll prepare our User model to use Mailboxer. Add the following line to your User model:

User > ActiveRecord::Base

Basic Mailboxer view

To create some test messages use the following method in the Rails console or set up a form in a view (replace “recipient_user_object” with a real User object from your app):

current_user.send_message(recipient_user_object, "body", "subject")

The quickest way to show the contents of your Inbox is to add the following line of code in your view:

<%= render current_user.mailbox.inbox %>
If you aren’t using Devise you can substitute current_user with any User object.
As you can see the output is pretty basic if we simply render the inbox using the above code. A bullet list is generated with the conversation subject and a “Move to Trash” link for each conversation.

Edit the Conversations controller

Before we edit our views we’ll need to add some code  to our Conversations controller. Add a conversations instance variable to our index action which will contain all of the user’s inbox messages:
class ConversationsController > ApplicationController
  before_filter :authenticate_user!
  helper_method :mailbox, :conversation
  def index
    @conversations = @mailbox.inbox.all

Create a reply action which will be called when replying to a message within a conversation:

def reply
 current_user.reply_to_conversation(conversation, params[:body])
 redirect_to conversation_path(@conversation)

Create a trash_folder action in your Conversations controller and add an instance variable which will contain all of the user’s messages in the Trash folder:

 def trashbin     
  @trash ||= current_user.mailbox.trash.all   

The above actions will handle our Inbox and Trash pages. However, we’ll also need to add actions for the Trash and Untrash actions. We will be adding a link on the Inbox page to allow the user to send a conversation to the Trash folder. We’ll also add an “Untrash” link on the Trash page to send a conversation back to the Inbox page. To do this, create the trash and untrash actions in the Conversations controller:

def trash
 redirect_to :conversations
def untrash
 redirect_to :back

Add an emtpy_trash action to the Conversations controller:

def empty_trash
  current_user.mailbox.trash.each do |conversation|
   conversation.receipts_for(current_user).update_all(:deleted => true)
 redirect_to :conversations

You’ll also need to add the following private methods called by the other methods mentioned above. They define @mailbox and @conversation:


def mailbox
 @mailbox ||= current_user.mailbox

def conversation
 @conversation ||= mailbox.conversations.find(params[:id])

Edit the Messages controller

We’ll need to add two actions to our Messages controller: new and create. These actions will be used to send a new message to a user, thus starting a new conversation:

class MessagesController > ApplicationController

  # GET /message/new
  def new
    @user = User.find(params[:user])
    @message =

   # POST /message/create
  def create
    @recipient = User.find(params[:user])
    current_user.send_message(@recipient, params[:body], params[:subject])
    flash[:notice] = "Message has been sent!"
    redirect_to :conversations

Customize the views

Mailboxer keeps track of the participants in a conversation. In our case, the only participants are the sender and the recipient. To show the sender of a message, loop through all of the participants and only show participants except for current_user:

<% @conversations.each do |conversation| %>
  <% if participant != current_user %>
    <%= %>
  <% end %>
 <% end %>

Conversation.subject can be used to display the conversation’s subject. You can have it link to the full conversation with this:

<%= link_to conversation.subject, conversation_path(conversation) %>

To show the date it was sent, you can use conversation.created_at. In the code below I’ll use update_at since conversations may last longer than a day. I’ll also use strftime to format the date into the “Sun, 01/01/2014 12:00 PM” format:

<%= conversation.updated_at.strftime("%a, %m/%e/%Y %I:%M %p") %>

Now for the Trash link. This link will call the trash action we setup in the controller above:

<%= link_to "Move to Trash", {:controller => "conversations", :action => "trash", :id =>}, :title=> "Move to Trash", :method=> 'post' %>

In the next section we’ll need to setup the routes so that the Trash links will work correctly. Before we move on to the routes we’ll need to customize the Trash page. The Trash page is going to be the same as above except for two things:

1. When looping through the participants to display the sender, change the first line to this:

<% @trash.each do |conversation| %>

2. Change the Trash link to an “untrash” link. Clicking on this link will send the conversation back to the Inbox:

<%= link_to "Move to Inbox", {:controller => "conversations", :action => "untrash", :id =>}, :title => "Move to Inbox", :method=>'post' %> 

Create a show.html.erb view page for a single Conversation. You’ll also want to include a messages form that allows the user to reply to a message within a conversation (we’ll create the form next):

<%= conversation.subject %>

A conversation with
<% @conversation.participants.each do |participant| %>
 <% if participant != current_user %>
  <%= %>
 <% end %>
<% end %>
<%= content_tag_for(:li, @conversation.receipts_for(current_user)) do |receipt| %>
 <% message = receipt.message %>
 <%= %>
 <%= simple_format h message.body %>
 Sent <%= time_ago_in_words(message.updated_at) %> ago

<% end %>

<%= render 'messages/form', conversation: @conversation %>

The messages form, named _form.html.erb in the Messages views folder, is a simple form that looks like this:

  <%= form_tag reply_conversation_path(conversation), method: :post do %>
 <%= text_area_tag 'body', nil, cols: 2, class: 'form-control', placeholder: 'Type your message here!', required: true %>
 <%= submit_tag "Send Message", class: 'btn btn-primary' %>
 <% end %>

Lastly, create a new message form that will be used to send a new message to a user and start a new conversation. Name this page new.html.erb within the messages view folder:

Send a message to <%= %>

<%= form_tag({controller: "messages", action: "create"}, method: :post) do %>
 <%= label_tag :subject %>
 <%= text_field_tag :subject %>
 <%= label :body, "Message text" %>
 <%= text_area_tag :body %>
 <%= hidden_field_tag(:user, "#{}") %>
 <%= submit_tag 'Send message', class: "btn btn-primary" %>
<% end %>

We’re almost there! The last thing we need to do is update the routes file.

Updating the routes

Add this to your routes:

resources :messages do
  member do
    post :new
resources :conversations do
  member do
    post :reply
    post :trash
    post :untrash
 collection do
    get :trashbin
    post :empty_trash

And that’s it! Please let me know if you have any questions.

68 Replies to “Customizing the Mailboxer Ruby Gem”

  1. Thanks for the tutorial! Following your code for the controller with the def index I am receiving a NoMethodError undefined method participant for #. Points to @conversations ||= current_user.mailbox.inbox.all . Is there a fix for this?

    1. Hi Cornelius! I’ll definitely do what I can to help troubleshoot the issue. Sorry I couldn’t reply sooner.

      1. Did you add `acts_as_messageable` to your User model?
      2. Did you manually create the conversations model? That may be the issue if you did. The mailboxer install script should take care of that configuration for you. You should NOT have a conversation model listed in your application’s models folder. If you already have a conversation model, remove it and rerun the install script and rake db:migrate.
      3. What version of Rails are you using? This was tested on 3.2.16.

      1. Thanks for getting back to me. I figured it out but ran out of time to come here to post a update afterwards.

        I do have a different question as I am not too familiar with the use of gems. Is it recommended to use the views from the mailboxer-app github or create custom views? Just for starting purposes to see view how everything works, as the final view would be different of course due to the web design added.

        I previously created my own inbox messaging system from scratch so I have views from it. But I’m not exactly 100% comfortable with gems. So was curious how should views be attack based on your experience with mailboxes.

        My inbox and messages view for my custom inbox system can be found at

      2. want to add an additional field(s) to the message form – Seems like there is no straight forward way to do so.

        From what i go at the moment you generate a migration:
        add_fields_to_mailboxer_notification example:string

        Then add the eample to the attr_accessible to the message model the in the view pass in the field. But the gem dosnt generate a message model.

        Any suggestions?

        1. Hello! I think the only way to do this is by adding them to the migration. Add your new fields to the migration and to your params in your messages controller (create action). Let me know if that works

  2. I have the view finished as I just worked off the example instead so I can get comfortable with the gem. This tutorial was well written and I am sure it’s going to help a bunch of people. About to fix a few small problems and I should be done with the gem. Thanks!

    1. Thanks for the kind words! I’m glad you were able to figure out the issue. As for your question posted in your other comment I think you’re totally on the right track. Play around with proven gems first and then create your own solution to fit your needs.

      Let me know if you need anything else. Good luck with your projects!

  3. Hey James, I do have one question as I been trying to solve something. I have a Question & Answers feature where a User can visit a profile and ask that user a question. This question will be sent to the users Inbox so they can choose to answer it. The issue I have as I modified the code to fit with mailboxer (I previously used this code on my custom inbox system) is that the Question gets created and is properly sent to the Notifications table, however the question is not assigned a conversation_id. I can’t seem to come up with the right formula that will allow the conversation_id to be created when a Question is made. Each time I do something I either produce a error or the Question no longer sends to the Notifications table. I created a Gist so you can view code at if you have the time. The file in question is the new.html.rb as that’s the view for the Questions form. I will continue working towards solving it but figured I would see if you could assist since you have experience with mailboxer. Thanks!

  4. I’m getting this error when linking to conversations_path

    formal argument cannot be an instance variable def trash_folder @trash ||= current_user.mailbox.trash.all end ^

    1. Hi Franklin, I think the issue here is actually a typo I had here on the tutorial. Sorry about that! I noticed in my example here that the controller action trash_folder did not match the route :trashbin. I just updated the code above. Try changing `def trash_folder` in your conversations controller to `def trashbin`.

  5. Hey James, Do you have an example of this on github? I’m fairly new to this and I seem to be messing up somewhere on the views. I just wanted to check if I was placing things in the right places.

  6. Thanks for posting this guide, James. I’ve been having a pretty difficult time getting this working, though. I think it would be a huge help if you included the location of each piece of code above it.

    i.e. the content for, say, the conversations#index action would have a comment above it like:

    # /app/views/conversations/index.html.erb

    I feel like I missed a few things or put them in the wrong spot because it wasn’t totally clear and nothing is working. I thought maybe I could just install the GUi example and go from there, but no…the GUI example ( is totally different than what this guide suggests to do.

    Anyway, putting:

    Shows nothing in the browser at all. I went ahead and tried to put all the necessary code from your guide above into the files I thought they should go into based on context and guessing, and I just started getting extremely weird/cryptic errors. I’ve since blown away the branch in Git to start over, but yeah…this gem seems to be a LOT of work and as much as I need a private messaging platform for the site I’m working on, I’m starting to think this gem is far too tedious.

  7. Hey James,

    I tried to post a comment earlier but I don’t know if it went through or not. I just wanted to let you know if I did, I tried your tutorial again and got it working this time. 🙂

    Thanks for posting. This gem is unnecessarily frustrating to get setup and working, but this was a huge help once I stopped trying to rush through it!

    1. Sorry about the late reply. I didn’t get a chance to view your post until this morning. I’m glad everything worked out for you! I understand your frustration. I ran into similar issues which is what prompted me to create this tutorial.

      1. No worries! Have you run into any issues with the messages#create action, though? I’m trying to create a new message from messages#new…I changed the recipients input to be a select of all users (there are only 12 and that’s the max there will ever be), and despite changing it from :recipients to :recipient and this line in messages#create to:

        @recipient = User.find(params[:recipient])

        I continue to get: “Couldn’t find User without an ID” for that line when attempting to send a message. If I send via the console or reply to an existing message (created through the console), it works fine. Starting a new one from the website, though, is not working. I’ve been Googling, but nothing I’ve found on Stack Overflow is of any help for this situation.

      2. I just don’t get this stupid gem.

        Why is it seemingly impossible to send a new message via webforms but doing the EXACT. SAME. THING. manually via the command line works just fine?

      3. Sorry again for the late reply. I don’t recall any issues with the Messages create action. If you want to send a message to all users then you should change it to

        @recipient = User.all

        I think the problem is that :recipient isn’t being passed to the app. You need to use :user so that it can grab the user ID from the URL. However, since you you need to send the message to all of the users, I would simply change the @recipient instance variable to all Users.

        What are you typing in command line in order to send messages to your users?

      4. I’m not trying to send to all users. I’m trying to just make a globally accessible way to send a message to anyone at any time. So instead of needing to go to another member’s page and clicking “Send x a message,” I just want to be able to click “Send a message” and then on the form page, select to whom I want the message to go from a dropdown (so people don’t need to memorize everyone’s email address).

        Maybe I’m just going about it wrong? I changed the field to be :recipient. Then, my messages_controller looks like:
        def new
        @message =

        # POST /message/create
        def create
        @recipient = User.find_by_email(params[:recipient])
        current_user.send_message(@recipient, params[:body], params[:subject])
        flash[:notice] = “Message has been sent!”
        redirect_to :conversations

        In this instance, I changed the :recipient field to just a text input for testing. I put in the email address of another user, put in a test message and subject and hit send…it posts, I get the success message and it redirects to /conversations and the new message isn’t there.

        Side note: I accidentally put my own email address in and sent myself a message and it worked exactly as it should. But using anyone else’s email address doesn’t.

        I can’t see anything in the logs that would tell me why it’s not working. And from the command line, I’m just doing:

        u1 = User.find(1)
        u2 = User.find(2)

        u1.send_message(u2, “Body here”, “Subject”)

        And it works brilliantly. I refresh the /conversations page and bam, it’s there.

      5. This is so weird…I restarted my computer to install a necessary update and when I booted the server back up and tested again because I’m a sucker for making myself angry…it worked. Messages are sending as they should be when I use a text box to manually type in email addresses. That’s a relief! Now I just need to figure out why the select wasn’t working…

        1. Glad everything worked out for you! This has definitely happened to me many times: you restart the server to install updates only to find your issues have been magically resolved!

      6. Have you run into any issues with sending messages in production? I just rolled out the update to my site that included the mailboxer gem. I sent a message to test and got a 500 error, of course. According to the logs:

        Errno::ECONNREFUSED (Connection refused – connect(2)):
        app/controllers/messages_controller.rb:13:in `create’

        And line 13 of messages_controller.rb is:
        current_user.send_message(@recipient, params[:body], params[:subject])

        The entire create action is:
        def create
        # @recipient = User.find_by_email(params[:recipient])
        @recipient = User.find(params[:recipient])
        current_user.send_message(@recipient, params[:body], params[:subject])
        flash[:notice] = “Message has been sent!”
        redirect_to :conversations

        I can see that the message sent when I go to the sentbox. The best I can tell from the logs is that, for some reason, after creating a new message, the site is trying to redirect to messages#index which doesn’t exist and I don’t know why it would be there is no redirect telling it to go there anywhere in the code. Everything works fine in development so I’m wondering if there’s something I overlooked about production that needs to be updated somewhere.

      7. Nevermind! I figured it out…I had to change config.uses_emails to false because I don’t have ActionMailer setup and running in production. Whew!

  8. This looks really helpful. Im new to rails so pardon if this is a clear cut issue.
    I did rails generate mailboxer:install but I got no controllers, views or models specific to Mailboxer. Do I need to individually create them?

  9. Hi James,

    I guess there is an error in your “”, and that you meant “” 🙂

    Secondly, I have a strange issue on my end. On my conversations index, called by the “render mailbox.inbox”, all my conversations are duplicated … They are all appearing twice … except if there is only one conversation !
    Strange issue. I guess it comes from the controller, but it seems ok .. (same as yours).

    If you have any clue, I’ll be grateful !

    Thanks again for your work,


  10. Hi James,

    I guess there is an error in your “”, and that you meant “” 🙂

    Secondly, I have a strange issue on my end. On my conversations index, called by the “render mailbox.inbox”, all my conversations are duplicated … They are all appearing twice … except if there is only one conversation !
    Strange issue. I guess it comes from the controller, but it seems ok .. (same as yours).

    If you have any clue, I’ll be grateful !

    Thanks again for your work,


    1. Oops. Error !
      I meant :
      I guess there is an error in your “, participant” , and that you meant “link_to, participant”

      1. Solved it !
        Apparently, your “” (right after your start paragraph “Customizing the views” is not necessary, as it is already done in the controller 🙂

        Hope I could help !


  11. Hi James, great article this really helped me a lot!

    I do have a problem though that I was hoping you could help me with regarding the inbox. I can send & receive messages and show them both in my views and controllers. However, my mailbox.inbox will not render when I run:

    I get output in my webbrowser that looks like quite plainly:
    = content_tag_for(:li, conversation) do |conversation| %p = link_to conversation.subject, conversation | – if conversation.is_completely_trashed?(current_user) = link_to ‘Untrash’, [:untrash, conversation], method: :post – else = link_to ‘Move to trash’, [:trash, conversation], method: :post

    Any idea why this is happening? I’ve tried a lot of things and can’t figure this out. If you have any time I’d greatly appreciate any help, thanks!

    1. Hi Peter,

      I’m glad you liked the tutorial! Does mailbox.inbox display the bulleted list of conversations or is it literally displaying Ruby code on the web page?

      A few things to check if you haven’t already:
      1. Make sure you are using the correct method to send messages. You need to use the send_message method.

      2. What’s the name of the file in question? You posted HAML code for your output. Your conversation show page should have a .haml extension, not .erb .

      3. Check your Conversations controller for any errors. How did you define your mailbox instance variable?

      Can you please post some of the relevant code? What do your Conversations controller and views look like? Paste them in a Github gist so it’s easier to read.


      1. Hi James,

        Thanks a lot for replying, I appreciate it!

        As I was about to finish going through the list you gave and tell you I couldn’t figure out the problem again, I realized I had left some other files in my conversations views from the sample app

        Apparently mailbox.inbox needs a _conversation.html.erb view and the page I pasted from the sample app had _conversation.html.haml. I deeleted the extra files and fixed up a _conversation.html.erb file by copying the show.html.erb file and my inbox renders now!

        Anyways thanks for the tutorial & inspiration, it was of great use!

  12. Hi James,

    Thanks very much for this tutorial, extremely informative, just one question; how would I modify the hidden_field_tag in the view so I could pass through multiple user IDs to message multiple users?

    Thanks again,


    1. Figured it out! Here’s my modified version of your controller code:

      def create
      @recipient = []
      attrs = params[:user].split(‘,’).each do |attri|

      current_user.send_message(@recipient, params[:body], params[:subject])

  13. Hi! do u have a demo app with this.
    Im very new to gems and dont know if i have to g Controller and Views manual and the add this stuff???

    1. Hi Frank! I’m sorry about replying to this so late. Yes, you will need to create the controller and views manually. Luckily there is already an open source application that has this code readily available! Check out the mailboxer-app on Github ( and use that code as a base. Copy/paste the controller and views into your own application and then follow along with my tutorial to customize it to your liking. Let me know if I can help with anything else. I’ll try to reply sooner!

      1. Yes I need a little help on the sent and reply part.
        I got a few messages from one user to another and vice versa with the console, so I know its working.
        When a user enters the message secction and creates a message with the form they can add the users(username from a multiselect) subject and body. I have the inbox, the trash and Sentbox working.I’m already on a 2-week deadline and I love to get this message system working. Thank you. Ill link the code to the post so you can take a look and give me a few pointers.

  14. I got this form

    true,:multiple => true, :include_blank => “Seleccione Usuario”%>


    conversation controller

    def create
    recipient = conversation_params(:recipients).split(‘,’)
    recipients = User.where(username: recipient).all
    conversation = current_user.send_message(recipients, *conversation_params(:body, :subject)).conversation

    redirect_to :conversations
    the problem that I got the form sent it and i can see it on my sentbox but on the other end user I cant see it on the inbox

    on chrome inspection:
    utf8 ✓
    conversation {“recipients”:[“”,”4″],”subject”:”Yeah”,”body”:”s”}
    commit send
    action create
    controller conversations

    1. Hi Frank,

      Did you add the Messages controller? To send individual messages, you need to create a new.html.erb (or haml) view that uses the Messages controller. Can you please update your StackOverflow question with the direct messaging form as well as your messages controller?


  15. Hi James
    I am a complete novice with rails, was wondering which file do you place the

    current_user.send_message(recipient_user_object, “Body”, “subject”)

    I am doing this for a school project so would appreciate if you could get back to me ASAP.
    I would really appreciate your help.

  16. Can you post the complete project with the views included. Because, I’m having trouble finding any sensible way of creating the front end portion within my web app using mail.html.erb

    1. I’ve been away from Rails development to work on other projects. I do intend to open source some of my work to help you all out! I’ll try to get something out there for everyone soon.

  17. I can’t seem to figure out how to get unread notifications.
    user.mailbox.notifications(unread: true)
    user.mailbox.notifications(unread: false)

    Give me the same results. Any ideas?

    Also, what actions makes a notification read?

    Thanks a lot

  18. Can we send email to user’s email account like gmail or outlook or rediffmail from our application, for instances like offers and all, using mailboxer?? If so, could you help me out with that please??

  19. Hi James,

    I need to implement chat support between users. Does this gem supports this. Does the conversation controller mean, it is for chatting?
    Please help me.


    1. You probably could implement the gem for live chatting if you created a script to refresh after you send a message. I only used the script for private messages (users don’t expect an immediate response). I would use this if you can’t find a reliable chat gem!

  20. I don’t see the MessagesController in the original demo. Is it needed? I have the new.html for conversations inside of the ConversationsController block.

  21. Hi James, thanks for this tutorial, I have a question, what if I want to implement the mailboxer gem between 2 models, I would need another conversations and messages controllers? What would you do in that case? thanks in advance..

    1. Hi Marcelo, sorry for the late reply. You should be able to just add acts_as_messageable to any model that needs mailboxer functionality. As for the controllers, it really depends on the implementation. Do the models need their own separate inboxes? What are your models and what functions do they serve in your application?

      If your two models are related and don’t need separate functionality then you could still use the same controllers. The models would be able to create, edit, and view the same bucket of conversations. You would only need separate conversation controllers if you wanted to logically separate conversations.

  22. Don’t worry James, my app have this 2 models, users and lawyers, users must be able to send messages to lawyers end they reply back, both models need to have their own inboxes but how can both have access to their conversation when they can’t share the same controller?

    1. All you need to do is add acts_as_messageable to your user and lawyer models and then you’re all set! Both models will be able to communicate with each other. Check out the official documentation for more info:

      Try following along with the tutorial using your two models (make sure both models have acts_as_messageable). Let me know if you run into any issues.

      EDIT: I just wanted to clarify that you don’t need to add any controllers. You still use the controllers that I mention in the tutorial. You don’t need to make another set of controllers. Also, for future reference, controllers can support logic to pull data from multiple models.

  23. Hi James, i think I’m almost done.. when the user sends a message from lawyer show page the message is send from lawyer email to himself, then I could reply just fine from the lawyer to the user, so I think my problem is the message create action, or the form…

    def new
    @user = User.find(params[:user])
    @message =
    # display form

    def create
    @recipient = Lawyer.find(params[:lawyer])
    current_user.send_message(@recipient, params[:body], params[:subject])

    flash[:notice] = “Message has been sent!”
    redirect_to :conversations

    Envia un mensaje a

    Hope you can help me…

  24. I don’t see any issues with the code samples you posted. I may need to see more. But first let’s verify that the data is correct. Take a look in your database. The mailboxer_receipts and mailboxer_notifications tables should tell you who sent the messages and who received them. If the sender and receiver id’s are correct then we can see if there is an issue with one of the views.

  25. I reviewed this on my phone but it looks like there may an issue with the hidden field in views/messages/new.html.erb. You are passing in lawyer id into the : user parameter.

    I’ll take a closer look either tonight or tomorrow.

Leave a Reply to resnate Cancel reply

Your email address will not be published. Required fields are marked *