Adam Yarger
Adam Yarger

Reputation: 63

Building an messaging system from scratch with multiple recipients in rails 4

Ive been trying to build an messaging system for my site which uses devise for authentication. The functionality it requires is to be able to send a message to either one or more recipients (preferably with a checklist form listing users as well). After searching for a while I found a couple gems such as mailboxer, but I didn't need all its features and wanted to build my own system for sake of learning (still a newbie at rails).

I have followed this ancient tutorial ( http://web.archive.org/web/20100823114059/http://www.novawave.net/public/rails_messaging_tutorial.html ). I realize this is a very old tutorial but it is the only one I could find which matched what I was trying to achieve.

I have followed the tutorial to a T and even copied and pasted the code from the tutorial after my code didn't work.

when trying to access http://localhost:3000/mailbox i get a NoMethodError in MailboxController#index

undefined method `messages' for nil:NilClass
app/controllers/mailbox_controller.rb:12:in `show'
app/controllers/mailbox_controller.rb:6:in `index'

I have also referenced this question Rails 3: undefined method messages for Folder which had the same error as me but the topic just seemed to go no where.

mailbox_controller.rb

  class MailboxController < ApplicationController

  def index

    @folder = current_user.inbox
    show
    render :action => "show"
  end

  def show
    @folder ||= current_user.folders.find_by(params[:id])
    @messages = @folder.messages :include       => :message, :order => "messages.created_at DESC"
  end
end

models/folder.rb

class Folder < ActiveRecord::Base
  acts_as_tree
  belongs_to :user
  has_many :messages, :class_name => "MessageCopy"
end

Any help with this would be awesome, also just let me know if you need any more info and will post it.

Upvotes: 2

Views: 669

Answers (1)

Adam Yarger
Adam Yarger

Reputation: 63

I ended up figuring out the messaging system with a few modifications. I wanted to post my whole solution since it gave me a difficult time and might be useful to others. I kept it very simple and did not include the the folder model which was giving me the problem in the first place, but none the less it is functioning.

Heres are my associations

model/message.rb

attr_reader :user_tokens

belongs_to :sender, :class_name => 'User'
has_many :recipients
has_many :users, :through => :recipients

def user_tokens=(ids)
    self.user_ids = ids
end

model/recipient.rb

belongs_to :message
belongs_to :user

model/user.rb

has_many :messages, :foreign_key => :sender_id

This is my messages controller

messages_controller.rb

def new
    @message = Message.new
    @user = current_user.following
    @users = User.all
    # @friends = User.pluck(:name, :id).sort
end

def create
    @message = current_user.messages.build(message_params)

    if @message.save
        flash[:success] = "Message Sent!"
        redirect_to messages_path
    else
        flash[:notice] = "Oops!"
        render 'new'
    end
end

def index
    @user = User.find(current_user)
    @messages = Recipient.where(:user_id => @user).order("created_at DESC")

end

private

    def message_params
        params.require(:message).permit(:body, :sender_id, user_tokens: [])
    end

My Views

_form.html.erb

  </div>
  <!-- displays the current users frinds their following -->
  <%= f.select :user_tokens, @user.collect {|x| [x.name, x.id]}, {}, :multiple => true, class: "form-control" %>
  <br>

  <div class="modal-footer">
    <%= f.button :submit, class: "btn btn-primary" %>
  </div>

Schema

messages_table

t.text     "body"
t.integer  "sender_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string   "body_html"

recipients_table

t.integer  "message_id"
t.integer  "user_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false

I hope this helps.

Upvotes: 3

Related Questions