Welcome to the Treehouse Community
The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

Zander Perry
2,227 PointsMessaging with Rails
Hey folks,
I'm working on adding messaging to the Treebook framework. I've looked at using mailboxer - https://github.com/ging/mailboxer - and was wondering if anybody had any luck or experience with it.
3 Answers

Zander Perry
2,227 PointsJason, thanks a ton for the reply! I figured that being the star that you are would preclude you from things like this. But in all seriousness I really appreciate it.
I played around with mailboxer for a couple days (including the accompanying 'rails-messaging' gem) and felt it was a little heavier-weight than I was looking for. So, I started updating an old Rails Messaging Tutorial and updating it for Rails 3.
Using this tutorial as a guide and Treebook's foundation (the same essential User and User_Friendship models) I was able to create an Inbox and Sent messages MVC (all playing nice with Devise). Where I've run into trouble is before and during the sent/create action.
I'm going to try and paste some code...
Models first:
class Message < ActiveRecord::Base
belongs_to :author, :class_name => "User"
has_many :message_copies
has_many :recipients, :through => :message_copies
before_create :prepare_copies
attr_accessor :to
attr_accessible :subject, :body, :to
def prepare_copies
return if to.blank?
else
to.each do |recipient|
recipient = User.find(recipient)
message_copies.build(:recipient_id => recipient.id, :folder_id =>
recipient.inbox.id)
end
end
end
class MessageCopy < ActiveRecord::Base
attr_accessible :folder_id, :message_id, :recipient_id
belongs_to :message
belongs_to :recipient, :class_name => "User"
belongs_to :folder
delegate :author, :created_at, :subject, :body, :recipients, :to => :message
end
class Folder < ActiveRecord::Base
attr_accessible :name, :parent_id, :user_id
acts_as_tree
belongs_to :user
has_many :messages, :class_name => "MessageCopy"
end
Controllers:
class SentController < ApplicationController
def index
@messages = current_user.sent_messages.paginate :per_page => 10, :page => params[:page], :order => "created_at DESC"
end
def show
@message = current_user.sent_messages.find(params[:id])
end
def new
@message = current_user.sent_messages.build
@user_friendships = current_user.user_friendships.all
end
def create
@message = current_user.sent_messages.build(params[:message])
if @message.save
flash[:notice] = "Message sent."
redirect_to :action => "index"
else
render :action => "new"
end
end
end
class MessagesController < ApplicationController
def show
@message = current_user.received_messages.find(params[:id])
end
end
class MailboxController < ApplicationController
def index
@folder = current_user.inbox
show
render action: :show
end
def show
@folder ||= current_user.folders.find(params[:id])
@messages = @folder.messages.paginate :per_page => 10, :page => params[:page], :include => :message, :order => "messages.created_at DESC"
end
end
View:
sent/new
<h2>Compose</h2>
<%= simple_form_for :message, :url => {:controller => "sent", :action => "create"} do |f| %>
<p>
To:
<select name="message[to][]">
<%= options_from_collection_for_select(@user_friendships.find(:all), :id, @message.to) %>
</select>
</p>
<p>Subject: <%= f.input :subject %></p>
<p>Body:<br /> <%= f.input :body %></p>
<p><%= submit_tag "Send" %></p>
<% end %>
So, unless I'm mistaken, what I need to do is somehow iterate over the current_user's friends and make them selectable (or even better typeahead) -> then send that friend/user's user_id (not user_friendship_id or friend_id) and have that create a message_copy in def prepare_copies in the Message model when it iterates over the user_id param passed in :to. I've been playing around with options_from_collection_for_select and prepare_copies but I'm still getting errors.
Any thoughts on getting sent/new.html.erb and message.rb (model) to pass the right params?
Thanks again!

Jason Seifer
Treehouse Guest TeacherTry this:
In your user friendship model:
def friend_name
friend.full_name
end
In your new page:
<%= options_from_collection_for_select(@user_friendships, :id, :friend_name) %>
I'm not 100% sure that will work but give it a shot.

Jason Seifer
Treehouse Guest TeacherHey Alexander, I've never used the mailboxer gem but it looks fine. I'd try following along with the sample application and making sure you know exactly what's going on in the gem first. You could even try using it as an example to implement your own version of a messaging system.