ruby-on-railsrubyruby-on-rails-4mailboxer

Limiting Mailboxer Conversations to be between specific users


I've followed the tutorial here: http://www.sitepoint.com/messaging-rails-mailboxer/ to implement the mailboxer gem into my application and its working as it should. However after implementing I am now required to somehow limit the conversations between users in a way that:

I think I need to make changes to the messages_helper module but I don't know what exactly to do.

Model User.rb

class User < ActiveRecord::Base

  enum role: [:student, :supervisor, :admin]
  after_initialize :set_default_role, :if => :new_record?

  has_many :students, class_name: "User",
                      foreign_key: "supervisor_id"

  belongs_to :supervisor, class_name: "User"

  has_and_belongs_to_many :pairings

  def set_default_role
    self.role ||= :student
  end

  def mailboxer_email(object)
    email
  end

  acts_as_messageable

end

Model Pairing.rb

class Pairing < ActiveRecord::Base

  has_and_belongs_to_many :supervisor, class_name: 'User'
  belongs_to :student, class_name: 'User'

end

Schema of these models (unrelated fields omitted)

create_table "pairings", force: :cascade do |t|
    t.integer  "supervisor_id"
    t.integer  "student_id"
    t.string   "project_title"
  end

  add_index "pairings", ["student_id"], name: "index_pairings_on_student_id", unique: true
  add_index "pairings", ["supervisor_id"], name: "index_pairings_on_supervisor_id"

create_table "users", force: :cascade do |t|
    t.string   "name"
    t.string   "email",                  default: "", null: false
    t.integer  "role"
  end

messages_controller.rb

class MessagesController < ApplicationController
  before_action :authenticate_user!

  def new
    @chosen_recipient = User.find_by(id: params[:to].to_i) if params[:to]
  end

  def create
    recipients = User.where(id: params['recipients'])
    conversation = current_user.send_message(recipients, params[:message][:body], params[:message][:subject]).conversation
    flash[:success] = "Message has been sent!"
    redirect_to conversation_path(conversation)
  end
end

messages_helper.rb

module MessagesHelper
  def recipients_options(chosen_recipient = nil)
    s = ''
    User.all.each do |user|
      s << "<option value='#{user.id}' #{'selected' if user == chosen_recipient}>#{user.name}</option>"
    end
    s.html_safe
  end
end

new.html.erb (view for sending messages)

<% header "Start Conversation" %>

<%= form_tag messages_path, method: :post do %>
  <div class="form-group">
    <%= label_tag 'message[subject]', 'Subject' %>
    <%= text_field_tag 'message[subject]', nil, class: 'form-control', required: true %>
  </div>

  <div class="form-group">
    <%= label_tag 'message[body]', 'Message' %>
    <%= text_area_tag 'message[body]', nil, cols: 3, class: 'form-control', required: true %>
  </div>

  <div class="form-group">
    <%= label_tag 'recipients', 'Choose recipients' %>
    <%= select_tag 'recipients', recipients_options(@chosen_recipient), multiple: true, class: 'form-control chosen-it' %>
  </div>

  <%= submit_tag 'Send', class: 'btn btn-primary' %>
<% end %>

Solution

  • Solved by making these changes

    module MessagesHelper
      def recipients_options(chosen_recipient = nil)
        s = ''
        current_id = current_user.id
        if current_user.try(:student?)
            User.joins('INNER JOIN "pairings" ON "pairings"."supervisor_id" = "users"."id"').where("pairings.student_id" => current_id).each do |user|
                s << "<option value='#{user.id}' #{'selected' if user == chosen_recipient}>#{user.name}</option>"
            end
        elsif current_user.try(:supervisor?)
            User.joins('INNER JOIN "pairings" ON "pairings"."student_id" = "users"."id"').where("pairings.supervisor_id" => current_id).each do |user|
                s << "<option value='#{user.id}' #{'selected' if user == chosen_recipient}>#{user.name}</option>"
            end
        else
            User.all.each do |user|
                s << "<option value='#{user.id}' #{'selected' if user == chosen_recipient}>#{user.name}</option>"
            end
    
        end
    
        s.html_safe
      end
    
    end