Update: This is post should be considered outdated.
This started with the help of this Rails Messaging Tutorial which I borrowed a used a couple lines of code from this tutorial to extend this project. So many thanks to manitoba98 and the guys at PingMe for writing acts_as_network.
There are so many things acts_as_network can be used for. So far I have used acts_as_network to allow users to be able to invite friends as well as receive friend requests from other members. It was also used to implement a way for users to block other users and I am using it for my messaging system. So I thought I would put this out there just to kind of show anyone who might be interested to see just how great acts_as_network is.
So I will assume you have installed the plugin. Follow the link above if you cannot find it otherwise. I am also using restful_authentication but you can use whatever.
After you install the plugin create a new model and controller
script/generate model Mail user_id:integer user_id_target:integer subject:string body:text recipient_deleted:boolean author_deleted:boolean
script/generate controller Messages index show new edit
In the migration setup
t.boolean :author_deleted, :default => ‘false’
t.boolean :recipient_deleted, :default => ‘false’
Now in your User Model add the association
class User < ActiveRecord::Base
acts_as_network :messages, :through => :mails,
end
Now in the Mail Model
class Mail < ActiveRecord::Base
belongs_to :user
belongs_to :user_target, :class_name => ‘User’, :foreign_key => ‘user_id_target’
validates_presence_of :user, :user_target, :body
Setup your Controller to look something like this…
class MessagesController < ApplicationController
before_filter :login_required
def index
@messages = (params[:folder] != ‘sent’) ? current_user.mails_in : current_user.mails_out
@folder = params[:folder]
end
def show
@message = Mail.find(params[:id])
@user = User.find(@message.user_id)
end
def new
@message = Mail.new
@target = User.find(params[:user_target])
end
def edit
@message = Mail.find(params[:id])
@subject = @message.subject.sub(/^(Re: )?/, “Re: “)
@target = User.find(@message.user_id)
end
def create
@message = Mail.new(:user => current_user, :user_target => User.find(params[:user_target]), :subject => params[:subject], :body => params[:body])
@message.save ? redirect_to(inbox_path) : render(:action => ‘new’, :user_targer => params[:user_target])
end
def update
@message = Mail.find(params[:id])
@message.toggle!(:recipient_deleted) ? redirect_to(inbox_path) : redirect_to(:action => ‘show’, :id => params[:id])
end
def destroy
@message = Mail.find(params[:id])
if @message.user_id == current_user.id
@message.update_attribute(“author_deleted”, true)
elsif @message.user_id_target == current_user.id
@message.update_attribute(“recipient_deleted”, true)
elsif @message.user_id == current_user.id && @message.user_id_target == current_user.id
@message.update_attributes(“recipient_deleted” => true, “author_deleted” => true)
end
redirect_to inbox_path
end
end
The index.html.erb I am about to show you is for an example only. It’s wasn’t written with DRY in mind. I’ll post some better looking code at some later point but for now this is what it is.
<table width=”100%” border=”0″>
<tr>
<th>Login</th>
<th>Subject</th>
<th>Sent</th>
</tr>
<% @messages.each do |message| %>
<% user = (@folder != ‘sent’)? User.find(message.user_id) : User.find(message.user_id_target) %>
<% if @folder == ‘inbox’ || @folder.blank? %>
<% if message.recipient_deleted == false %>
<tr>
<td><%= link_to user.login, user_path(user) %></td>
<td><%= link_to message.subject, message_path(message) %></td>
<td><%= distance_of_time_in_words(message.created_at, Time.now) %> ago</td>
</tr>
<% end %>
<% elsif @folder == ‘sent’ %>
<% if message.author_deleted == false %>
<tr>
<td><%= link_to user.login, user_path(user) %></td>
<td><%= link_to message.subject, message_path(message) %></td>
<td><%= distance_of_time_in_words(message.created_at, Time.now) %> ago</td>
</tr>
<% end %>
<% elsif @folder == ‘trash’ %>
<% if message.recipient_deleted == true %>
<tr>
<td><%= link_to user.login, user_path(user) %></td>
<td><%= link_to message.subject, message_path(message) %></td>
<td><%= distance_of_time_in_words(message.created_at, Time.now) %> ago</td>
</tr>
<% end %>
<% end %>
<% end %>
</table>
</div>
edit.html.erb
<% form_tag ‘/messages/create’ do %>
<ul>
<li><label for=”user_target”>To:</label> <%=h @target.login %><%= hidden_field_tag ‘user_target’, @target.id %></li>
<li><label for=”subject”>Subject:</label> <%= text_field_tag ‘subject’, @subject %></li>
<li><label for=”body”>Body:</label><br /> <%= text_area_tag ‘body’, @body %></li>
<li><%= submit_tag ‘Create’ %></li>
</ul>
<% end %>
new.html.erb
<div id=”message_new”>
<% form_tag ‘/messages/create’ do %>
<ul>
<li><label for=”user_target”>To:</label> <%=h @target.login %><%= hidden_field_tag ‘user_target’, @target.id %></li>
<li><label for=”subject”>Subject:</label> <%= text_field_tag ‘subject’, ” ,:class=>”text” %></li>
<li><label for=”body”>Body:</label><br /> <%= text_area_tag ‘body’ %></li>
<li><%= submit_tag ‘Create’ %></li>
</ul>
<% end %>
</div>
show.html.erb
<div id=”message_show”>
<ul>
<li>Subject: <%=h @message.subject %></li>
<li>From: <%=h @user.login %></li>
<li class=”body”>Body:<br /><br /><%= @message.body %></li>
<li><%= link_to ‘Reply’, edit_message_path %> | <%= link_to ‘Trash’, message_path(@message), :method => :delete %></li>
</ul>
</div>
routes.rb: map.resources :messages
map.inbox ‘/inbox’, :controller => ‘messages’, :action => ‘index’, :folder => ‘inbox’
map.sent ‘/sent’, :controller => ‘messages’, :action => ‘index’, :folder => ‘sent’
And that should about do it.
del.icio.us Tags:
ruby,
rails,
ror,
rubyonrails,
plugins,
social,
messaging,
howto,
acts_as_network,
habtm,
hamt,
database,
association,
socialnetwork,
socialnetworking