Skip to content

Add social networking to your rails application. This is a tutorial showing how to use the Has Many Friends plugin with a few bells and whistles. Includes example code.

Notifications You must be signed in to change notification settings

XFinger/HasManyFriends_tutorial

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Rails Has Many Friends Plugin Tutorial

Add social networking to your site with the Has Many Friends plugin. With this tutorial your site users can search for other users by email address and send a friend request. If the request is accepted, a friendship is established and the social networking commences. If the searched for site user is not yet a member, an email invitation can be sent out.

This tutorial assumes that you already have a base project set up with a users table that has login and email columns. If you are starting from scratch I suggest you take a look at the Cortex Engine — a base rails setup that includes user authentication with authlogic, action-mailers and a few other features to get you up and running.

This tutorial uses a little bit of Ajax and requires that prototype is linked to in the head section of your layout. If you are using the Cortex Engine please see the JavaScript section of the readme.

Get Started

Install the HasManyFriends plugin

script/plugin install git://github.com/swemoney/has_many_friends.git

Run the generator

script/generate hmf_friendship_model Friendship

This will set up your friendship model and create a migration file:

class CreateFriendships < ActiveRecord::Migration
  def self.up
    create_table :friendships, :force => true do |t|
      t.column "user_id",     :integer, :null => false
      t.column "friend_id",   :integer, :null => false
      t.column "created_at",  :datetime
      t.column "accepted_at", :datetime
    end
  end
  def self.down
    drop_table :friendships
  end
end

Rake the migration

rake db:migrate

Generate a controller

script/generate controller friendships

friendships_controller.rb

The invitation action uses action-mailer to send invitations to become a site member. We will write the mailer part later in the tutorial. Notice: the format.js in the respond_to block, we need this for our Ajax function (invitation.rjs).

def invitation
   user = current_user
   recipient = params[:email]    
     UserMailer.deliver_invite(user, recipient)
     flash[:notice] = "Invitation Sent"  
      respond_to do |format|
       format.html
       format.js 
      end
 end

The index action lets us search for friends and returns an Ajax response.

def index
    @lookup = params[:search]
    @result= User.find(:first, :conditions =>['email = ?', @lookup ]) 
    @friends = current_user.friends
    respond_to do |format|
      format.html
      format.js 
    end
 end 

The show action

def show   
    @friends = current_user.friends
    @pending_by_me = current_user.pending_friends_by_me
    @pending_for_me = current_user.pending_friends_for_me  
  end

The new action initiates the friendship by sending a request to the specified user.

def new
   @user=current_user
   @rf = User.find(params[:id])
   @user.request_friendship_with @rf
   flash[:notice] = "sent friendship request to #{@rf.login.capitalize} " 
   redirect_to :back 
 end 

The accept action completes the frindship

def accept
    @user=current_user    
    @accept = User.find(params[:id])
    @user.accept_friendship_with @accept    
     redirect_to :back
  end

The sever action deletes the friendship

def sever
    @user = current_user
    @id = params[:id]
    @sever = User.find(@id)
    @user.delete_friendship_with @sever
    flash[:notice] = "friendship canceled"  
    redirect_to :back      
  end 

Add routing to config/routes

map.resources :friendships

View Templates

show.html.erb

The show template handles 5 different actions. It displays a friends list, contains a search form that returns an Ajax response, displays a list of friendship requests (from other users) and displays a list of sent friendship requests.

<h3>Manage Friends</h3> 
<b>My Friends</b><br>
   <%@friends.each do |fr| %>	
     <%= fr.login.capitalize %>  
     <%= link_to "Delete",  :controller => 'friendships', :action => 'sever', :id => fr.id %>
   <%end%>
<% form_remote_tag  :url => '/friendships/index'  do  %>
    Find friends by email address
    <%=  text_field_tag :search, params[:search], :size => 20  %>
    <%= submit_tag "Search" %>
<% end %>
<div id = 'ajax_space'></div>  <!-- provides a space for the Ajax response-->			
<% if @pending_for_me.size > 0 %><!-- only displays if user has friendship requests -->
    <div>
      <b>Frindship Requests:</b>
      <ul>
         <% @pending_for_me.each do |pfm|%>				
	 <li>
	     <%= pfm.login.capitalize %>,
             <%= pfm.email%> 
	     <%= link_to ' ...Accept', :controller => 'friendships', :action => 'accept', :id => pfm.id %> 
	 </li> 
	 <%end%>
      </ul>
</div>
<%end%>
<% if @pending_by_me.size > 0 %><!-- only displays if user has pending friendship requests -->		 
  <div>
    <b>You have sent a friendship request to:</b>
    <ul>
       <% @pending_by_me.each do |pbf|%>
         <li><%= pbf.login.capitalize %>, <%= pbf.email%> </li>	
       <%end%>
    </ul>
  </div>
<%end%>		

_index.html.erb

The index partial shows the search response

<% if @result.blank? %>
  A user with email: <b><%= @lookup %></b> was not found. 
  <%= link_to_remote 'Email an invitation?', :url=> {:controller => 'friendships',
  :action =>'invitation', :email => @lookup}, :method => 'post'%>
<%else%>
  User found: 
  <%= @result.login.capitalize%>,   
  <%= @result.email %>
  <% if @friends.include? @result %>
     is already in your share list.  
  <%else%>  	
    <%= link_to 'Send Share Request?', :controller => 'friendships', :action => 'new', :id => @result.id%>
  <%end%>
<%end%>

Ajax

invitation.rjs

page.reload
page[:search].value = ""

index.rjs

page.insert_html :bottom, :ajax_space, :partial => 'index'
flash.discard

Action-mailer

The mailer settings are set up to use smtp with gmail.

models/user_mailer.rb

class UserMailer < ActionMailer::Base    
  def invite(user, recipient) 
    @user=user
    @subject = "Invitation"
    @from = "my website"
    @body[:url] = "http://192.168.1.3:3004"  #set to your ip address or domain name
    @recipients = recipient
    @sent_on = Time.now
    content_type 'text/html' 
  end
end

config/initializers/smtp_gmail.rb

require "smtp_tls"    
  mailer_config = File.open("#{RAILS_ROOT}/config/mailer.yml") 
  mailer_options = YAML.load(mailer_config) 
  ActionMailer::Base.smtp_settings = mailer_options 
ActionMailer::Base.smtp_settings = {
   :address => "smtp.gmail.com",
   :port => 587,
   :authentication => :plain,
   :enable_starttls_auto => true,
   :user_name => "your gmail address",
   :password => "your gmail password"
 }

config/mailer.yml

:address: smtp.gmail.com
  :port: 587
  :user_name: your gmail address 
  :authentication: plain

user_mailer/invite.html.erb — html mail template

<!DOCTYPE html>
<html>
  <head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
  </head>
  <body>
    <h4>Welcome, </h4>
    <p>
       <%= @user.login.capitalize %> ( <%= @user.email %> ) has invited you to join this web site.
    </p>
    <p>
      To sign up or for more information go to <%= @url %>.
    </p>
    <p>Thanks, <br>
	 The Web
	</p>
  </body>
</html>

user_mailer/invite.text.erb — plain text template

Welcome, 
<%= @user.login.capitalize %> (<%= @user.email %>) has invited you to join this web site.
To sign up or for more information go to <%= @url %>. 	
Thanks,
The Web

Fire up your server and test everything out.

Relevant Links

About

Add social networking to your rails application. This is a tutorial showing how to use the Has Many Friends plugin with a few bells and whistles. Includes example code.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published