A Simple Twitter App with Ruby on Rails – Building Friendships
Introduction
This is the third and final part of series on how to create a twitter style web application with Ruby on Rails. This part will cover how to add friendships between users.- The first part of this tutorial: A Simple Twitter App with Ruby on Rails – Messages With Ajax
- The second part of this tutorial: A Simple Twitter App with Ruby on Rails – User Authentication
Self-Referential Relationship
Image by pikisuperstar on Freepik
To create friendships between users we have to deal with a special type of association, which is called a self referential relationship. It is called this because the model (in this case, User) references itself. Why? Well if a given "user" has many "friends", those "friends" are also "users". Furthermore, each of those friends can also have friends, so we are dealing with a many to many relationship. The relationship can affectively be called a "friendship" because friendships can be gained and lost (as in real life). So, let's create the friendship model with two foreign keys.> ruby script/generate model friendship user_id:integer friend_id:integerNow, migrate the database:-
> rake db:migrate
Making and Losing Friends
Image by standret on Freepik
We will need to create and destroy friendships and for this we will need a controller for friendships:-> ruby script/generate controller friendshipsNow add the create and destroy methods as shown below:-
class FriendshipsController < ApplicationController def create @friendship = current_user.friendships.build(:friend_id => params[:friend_id]) if @friendship.save flash[:notice] = "Added friend." redirect_to root_url else flash[:error] = "Error occurred when adding friend." redirect_to root_url end end def destroy @friendship = current_user.friendships.find(params[:id]) @friendship.destroy flash[:notice] = "Successfully destroyed friendship." redirect_to root_url end endSo, what exactly do we relate the user model to?? Well, first we need to specify that the friendship model belongs to a friend (which is actually a user!). You can do this by adding some more lines to the user model:-
class Friendship < ActiveRecord::Base ... belongs_to :friend, :class_name => "User" endWe need to add two lines to the User model. A User has many friendships and has many friends through friendships. This reads almost exactly as it is coded, which is a testament to Ruby on Rails.
class User < ActiveRecord::Base has_many :friendships has_many :friends, :through => :friendships ... end
Listing your Friends
Image by Freepik If we want to list all the registered users and allow the current user to befriend other users, then we will need to create a new view in the users folder called index.html.erb:-< % @users.each do |user| %>
Now, let's put the controller actions in place. Open the users_controller file and add the index and show methods.
< % if user.username != current_user.username %> < %=h user.username %> < %= link_to "Add Friend", friendships_path(:friend_id => user), :method => :post %> < % end %>
< % end %>class UsersController < ApplicationController def index @users = User.all end def show @user = current_user end ... endWe need to do two more things before we can give this a whirl. First add the friendships resource to the routes file:-
map.resources :friendships...and finally, we can add some links on the posts/index.html.erb file:-
...< %= link_to "Make Friends", users_path %> < %= link_to "My Friends", { :controller => "users", :action => "show", :id => current_user } %> Ok, we can now start up the server and browse to http://localhost:3000 to have a look.
Beautiful code. and very well written tutorial.
Thanks.
I just finished doing some analysis on modeling friendships myself. Here are a few other resources I found useful:
swemoney’s has_many_friends plugin, which while no longer in active development, is worth reviewing the source code for some ideas for convenience methods and an alternative association model.
http://github.com/swemoney/has_many_friends/tree/master
There is also a few excellent questions on stackoverflow addressing this scenario:
http://stackoverflow.com/questions/623909/rails-model-with-foreignkey-and-link-table/623956#624261
http://stackoverflow.com/questions/1071014/rails-two-way-friendship-model-contd
And, of course, Ryan Bates’ railscast:
http://railscasts.com/episodes/163-self-referential-association
Don’t work in rails but interesting tutorial nonetheless. Code is quite clear.
Thanks, simple and well explained.
how to upgrate my photoshop skill.
Every new idea is a new reflexion i will google it
helpful tutorial. Thanks.
nice!!
Tutorial added to TheWebTuts
Is there something missing in this tut?
Where did you write “Find New Friends”?
Can you post the code for /users/show.html.erb it’s not in the tutorial
nevermind found it here
http://github.com/overture8/Twitter-Blog-Demo/blob/master/app/views/users/show.html.erb
you need to create /users/show.html.erb file and code is:
Username:
Friends
– :delete %>