Thursday, October 4, 2007

acts_as_messageable plugin released!

Problem:

Private messaging in Rails.

Solution:

acts_as_messageable

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.

Saturday, June 30, 2007

Rails + Memcached = Undefined Class/Module

Problem:

When using memcached, if you store Model objects in the cache, when you go to load to object back out it doesn't know about your Model classes and throws an 'Undefined Class/Module' error. The old solution for this was to add the 'model' method to the top of your controller and list the models that were needed. This is now deprecated.

Solution:

before_filter  :preload_models
 
def preload_models()
  Model1
  Model2
  ...
  ...
  ...
  Model9
end

What it do?

This is more of a hack than a solution, but it works. Add the above code to your application controller and list all the models you are storing in memcached as well as any associations that are also being stored. Referencing the Model class name must trigger a load that loading from memcached does not.

Rails Page Caching and MIME Types

Problem:

Regardless of what your template file extension is, after a page is cached using page caching the content will be served as text/html. This is fine in most cases, but what if you are caching rss or ical feeds? Rails offers a 'page_cache_extension' attribute which allows you to set the cached file extension to whatever you like but this is a class attribute and will cause all cached pages to be of this type, pretty much useless.

Solution:

<LocationMatch \/(rss)\/?>
    ForceType text/xml;charset=utf-8
</LocationMatch>
<LocationMatch \/(ical)\/?>
    ForceType text/calendar;charset=utf-8
</LocationMatch>

What it do?

This solution assumes that you are running apache. Add the above to your apache config within the VirtualHost directive. This examines the requested location and forces a MIME type for locations that match the regex. Locations that match '/rss' or '/rss/' will be served as 'text/xml' and locations that match '/ical' or '/ical/' will be served as 'text/calendar'. Done.