Problem:
Private messaging in Rails.
Solution:
What it do?
acts_as_messageable is a plugin for enabling private messaging between users. Conversations, multiple recipients, trash, sentbox... its all in there.
to install:
> script/plugin install http://actsasmessageable.googlecode.com/svn/tags/acts_as_messageable-1.0.1 > script/generate messageable > rake db:migrate
to use:
class User < ActiveRecord::Base acts_as_messageable end
sending:
phil = User.find(3123) todd = User.find(4141) phil.send_message(todd, "whats up for tonight?", "hey guy")
sends a mail to todd's inbox and puts the sent message in phil's sentbox.
retrieving:
todd.mailbox[:inbox].unread_mail
returns an array of all unread mail messages in todd's inbox.
replying:
mail = todd.mailbox[:inbox].unread_mail[0] todd.reply_to_sender(mail, "not sure, probably having a few dozen cocktails.")
replys to the sender of the mail message. (Messages can be sent to multiple users, and are conversation based. See the RDoc.)
moving / deleting:
convo = mail.conversation todd.mailbox.move_to(:trash, :conversation => convo)
moves all mail messages to the 'trash' that are part of the given conversation. There are 3 default mailboxes for each user (:inbox, :sentbox, :trash), although any name can be passed to this method if you wanted to implement folders.
bonus:
todd.mailbox[:inbox].latest_mail
returns the last message received for each conversation you are involved in. Pretty sweet for an inbox view.
Check the RDoc.

23 comments:
Phil,
Are you currently using this in a project, and if so how large? If I may ask.
yes I am currently using this on bandsintown.com.
Awesome! Thanks Phil! This is a really nice little plugin and fairly well documented. I'm trying to implement a little message system with it now and I think I'm missing something (like confusing Messages and Mail) because I can't figure out how to get individual Message objects directly from the mailbox...
I'd like to do something like this:
@messages = current_user.mailbox[:inbox].messages
but, instead I'm using the very cludgy:
current_user.mailbox[:inbox].mail.each do |mail|
@messages << Message.find(mail.message_id)
end
Can someone post an example of the best way to get an individual message or array of messages to send to an inbox or message view?
Thanks!
Peter
ps. Bandsintown.com is pretty sweet...
A mail is just basically a wrapper for a message which holds individual info on the message (read, trashed, mailbox). So if someone sent a message to 20 recipients there would only be 1 message created and 20 mails.
It was confusing for me building it too but I believe this is the correct approach.
I think what you are actually after are the mail objects. If you go directly to the messages then you can not see the read state.
so you could just render the mail array as a collection and access the info with:
mail.message.message
mail.message.subject
mail.read
I also use CachedModel on my messages which really speeds this up.
latest_mail() is also really nice for an inbox view if you are going with the conversation approach... similar to how gmail inbox works, only showing you the latest message for each convo you are involved in.
Im on no sleep so I hope im making sense... let me know if you have any other questions.
glad you like bandsintown.
Aahhh, I see... yes, that's exactly what I wanted. I'll check out CachedModel next and maybe dive into the folder & conversation features later... Thanks again!
no problem... glad to see youre using it.
Could you please post some examples how to write the controller and views? The stuff posted above doesn't really say anything. Nor does the Rdoc...
I will post some more examples later on tonight.
I don't want to push you or anything... ;) Put you got some examples up your sleeve? Else I move on to another plugin that I know works out-of-the-box.
It does work out of the box i just chose not to include controller/views because they tend to be very custom... anyway here are some examples:
example url:
-------------
#user/:id/mail/:type
/user/3/mail/inbox
controller:
-------------
def mail()
@user = User.find(params[:id])
@mail = @user.mailbox[params[:type]].latest_mail
end
view:
------------
<%= render(:partial => '/shared/mail', :collection => @mail %>
in that partial you could just access the mail info through:
mail.message.message
mail.message.subject
mail.read
Just a simple example but that should get you going.
-Phil
looks cool. I am going to use it right way in my project. Will post the experience
I have posted an issue that was occurring in migration
http://code.google.com/p/actsasmessageable/issues/detail?id=1
Also can you plz post the routes that you are using in your project esp the nested one.
Thanks,
Aroop
@aroop
Thanks for reporting that bug, I have applied a fix and the new version is available here:
http://actsasmessageable.googlecode.com/svn/tags/acts_as_messageable-1.0.1
also for the routes im using something like this:
/user/:id/mail/:mailbox_type
(for inbox, sentbox, trash, etc.)
/user/:id/convo/:convo_id
(for reading conversations)
here is the new version link if you can't see it in my last comment:
new version
Phil,
Your site (BandsInTown) absolutely rocks! Congrats!
Is the acts_as_messageable plugin already Rails 2.0 compatible?
Cheers, Sazima
I am not sure, I havent made the switch yet. If you find out please let me know.
Phil,
Apparently "acts_as_messageable" is Rails 2.0.2 compatible!
But unfortunately I'm very confused on how to use it...
Any chance you could post or send me an example application (basically routes, controllers and views)?
Cheers, Sazima
Hello. This post is likeable, and your blog is very interesting, congratulations :-). I will add in my blogroll =). If possible gives a last there on my blog, it is about the Celular, I hope you enjoy. The address is http://telefone-celular-brasil.blogspot.com. A hug.
Phil,
This is a wicked plugin, great job!!! I am however, trying to implement this plugin along with the Goldberg authentication plugin, and running into problems. The Goldberg plugin has a user table, with a user.rb which includes a Goldberg module. I basically tried to change reference class_names from User to Goldberg::User and encounter an error stating 'undefined method 'mail' for Goldberg::User:class..I also tried to create a user.rb with the following inheritance
User < Goldberg::User and get the same error..but stating 'undefined method 'mail' for User:Class?
Is this due to the line in the mail.rb? self.table_name = "mail", any clues on how to integrate both.
Thanks, in advance,
Dmarc
Phil, it is a good plugin. good work.
I wonder if it is possible that you share your views also. I know views could vary very much but you know, it is messaging, it will be almost same everywhere, if not it will present a good example for the people.
simply the views in bandsintown.com will do..
thanks!
I am trying to get this plugin to work within a rails 2.0.2 application but i run into a weird problem.
When trying to access the mailbox and its mails from the rails console everything works as expected:
u = User.find(:first)
mb = u.mailbox[:inbox]
mb.mail.each { |mail| puts mail.message.subject }
But when used within a controller/view in a similar way only the first call works.
Every call after throws
undefined method `message' for #< Mail:0x6878614 >
Any Ideas whats going wrong?
Post a Comment