Question

I'm using the mailboxer gem to implement user messaging on an app. Currently, i've got it set up based on this https://github.com/RKushnir/mailboxer-app. Users can enter an email address, subject and message into a form, and start a conversation.

I'd like a user to be able to start a conversation without having to enter another users email address - for instance clicking a button on a relevant page where I can pass a @user in as the recipient.

Here is my current controller:

class ConversationsController < ApplicationController
      authorize_resource
      helper_method :mailbox, :conversation


      def create
        recipient_emails = conversation_params(:recipients).split(',')
        recipients = User.where(email: recipient_emails).all

        conversation = current_user.
          send_message(recipients, *conversation_params(:body, :subject)).conversation

        redirect_to conversation
      end

      def reply
        current_user.reply_to_conversation(conversation, *message_params(:body, :subject))
        redirect_to conversation
      end

      def trash
        conversation.move_to_trash(current_user)
        redirect_to :conversations
      end

      def untrash
        conversation.untrash(current_user)
        redirect_to :conversations
      end

      private

      def mailbox
        @mailbox ||= current_user.mailbox
      end

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

      def conversation_params(*keys)
        fetch_params(:conversation, *keys)
      end

      def message_params(*keys)
        fetch_params(:message, *keys)
      end

      def fetch_params(key, *subkeys)
        params[key].instance_eval do
          case subkeys.size
          when 0 then self
          when 1 then self[subkeys.first]
          else subkeys.map{|k| self[k] }
          end
        end
      end
    end

and corresponding _form:

<%= form_for :conversation, url: :conversations do |f| %>
      <%= f.text_field :recipients %>
      <%= f.text_field :subject %>
      <%= f.text_field :body %>
      <div class="form-actions">
        <%= f.button :submit, class: 'btn-primary' %>
        <%= submit_tag 'Cancel', type: :reset, class: 'btn btn-danger' %>
      </div>
    <% end %>

I've got all the views and actions working relating to replying to conversations with messages, display all users conversations etc, but just not how to start it without having to type the address in.

Thanks for any help

Added: I don't mind editing the above form etc and losing the capability for a user to enter another's email, as I don't want them to be able to do that. The buttons in question will be named along the lines of 'ask the client a question', or 'ask the venue a question', rather than just sending messages to random users.

EDITED TO ADD:

Thanks for that, makes sense and I am nearly there...

I've ended up adding a copy of the original conversation form i'm using (in my _form file):

 <%= form_for :conversation, url: :conversations do |f| %>
        <%= f.text_field :recipients %>
        <%= f.text_field :subject %>
        <%= f.text_field :body %>
        <div class="form-actions">
          <%= f.button :submit, class: 'btn-primary' %>
          <%= submit_tag 'Cancel', type: :reset, class: 'btn btn-danger' %>
        </div>
      <% end %>

This works fine from the correct view that I need it in, and does everything as expected - however, when I try to hide the recipients text field and pass in the users email address (rather than having to manually type it in, I am getting problems:

 <%= form_for :conversation, url: :conversations do |f| %>
        <%= hidden_field_tag :recipients, "#{@enquiry.client.user.email}" %>
        <%= f.text_field :subject %>
        <%= f.text_field :body %>
        <div class="form-actions">
          <%= f.button :submit, class: 'btn-primary' %>
          <%= submit_tag 'Cancel', type: :reset, class: 'btn btn-danger' %>
        </div>
      <% end %>

This is throwing an error in the controller:

undefined method `split' for nil:NilClass

 def create
recipient_emails = conversation_params(:recipients).split(',')
recipients = User.where(email: recipient_emails).all
conversation = current_user. 

If I 'view source' on Firefox before I hit submit on the form, I can see that there is a field there with the users email address passed in correctly, but it's just not going to the controller for some reason?

Something that may help - If I change the hidden_field_tag back to a normal field, and pass in the email address as above, the view won't even load. It is saying 'undefined method `merge' for "user@user.com":String and highlighting that row in the code.

Thanks

Was it helpful?

Solution

In mailboxer, you do not send a message to an email address, rather you send it to a model which has acts_as_messageable on it, such as user. The following code is a rough implementation of how I have done it, with the @user variable being set in the controller, as this is on the profile page.

<%= form_tag("/messages/send_message", method: "post", url: send_message_path) do  %>
<%= hidden_field_tag :user_id, "#{@user.id}" %>
<%= text_field_tag :subject, nil, :class => 'form-control', :placeholder => "Subject" %>
<%= text_area_tag :message, nil, :class => 'form-control', :placeholder => "Message" %>
<%= submit_tag "Submit", :class => "btn btn-primary" %>
<% end %>

This would have an action you messages controller like this:

def send_message
@user = User.find(params[:user_id])
@message = params[:message]
@subject = params[:subject]
current_user.send_message(@user, "#{@message}", "#{@subject}")
redirect_to root_path
end

Or, in your case, if you wanted email addresses, you can just find the recipients by there email address which you have in the database:

def send_message
@user = User.find_by_email(params[:user_email])
@message = params[:message]
@subject = params[:subject]
current_user.send_message(@user, "#{@message}", "#{@subject}")
redirect_to root_path
end

And something like this in you routes file:

post '/messages/send_message', :to => "messages#send_message", :as => "send_message"

Really hope this helps!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top