Tutorial on developing a Facebook platform application with Ruby On Rails
June 29th, 2007
If you havn’t heard of Facebook. Where you been, living in a cave! Well you also probably know that in June 2007 Facebook opened a development platform for integrating new applications into Facebook, also codenamed F8. By the 24th June there were a 1,000 new applications available for the Facebook networkers to play with. According to both the online and traditional news media, Facebook have changed the game.
Well ZDNet are reporting that 1,000 developers a day are joining Facebook platform. That as it may, they are not all creating applications right away. The documentation is patchy, spread-out, difficult to understand and incomplete. It is a wonder so many applications are built because there is pain to go through to get there.
But this article is a complete tutorial for building a simple Facebook application in Ruby On Rails and should allow you to hit the ground running. We are going to create a recipes sharing application for Facebook from scratch.
UPDATE: The second part can be found here
UPDATE: This article is a bit out of date now, I have now posted an article on Rails, resful_authentication and Facebook connect
If you havn’t heard of Facebook. Where you been, living in a cave! Well you also probably know that in June 2007 Facebook opened a development platform for integrating new applications into Facebook, also codenamed F8. By the 24th June there were a 1,000 new applications available for the Facebook networkers to play with. According to both the online and traditional news media, Facebook have changed the game.
Well ZDNet are reporting that 1,000 developers a day are joining Facebook platform. That as it may, they are not all creating applications right away. The documentation is patchy, spread-out, difficult to understand and incomplete. It is a wonder so many applications are built because there is pain to go through to get there.
But this article is a complete tutorial for building a simple Facebook application in Ruby On Rails and should allow you to hit the ground running. We are going to create a recipes sharing application for Facebook from scratch.
UPDATE: The second part can be found here
First of all some useful links:- Facebook Developers
- Facebook Documentation
- Facebook Developers Wiki
- Ruby On Rails Facebook Application Forum
Facebook has provided many different integration points and different APIs to an application so it is worth reading Anatomy of a Facebook Application first which will explain the areas an application can affect for a user.
There are two different types of Facebook application- A desktop application
- A website application
We are only going to be concerned with website applications for now. There is also 3 different ways an application can interact with Facebook.
- As an external application but interacting with the remote API
- Running in an IFRAME on the Facebook site
- Running in a Facebook canvas and using Facebook Markup Language (FBML)
The application can use one or all of these techniques. We are going to try all three in this tutorial.
But first lets start by creating a Rails application with NO Facebook stuff and then we’ll look at FB-ing it. Originally I planned to do this completely RESTfully but it turns out it doesn’t work well with Facebook canvas, so it’s old-skool Rails i’m afraid.
Lets create the application:
rails socialrecipe
cd socialrecipe
And create some models. We are keeping this application very simple for demo purposes so just a recipe and a comment model needed. (you will need to concate these lines properly)
ruby script/generate model Recipe
title:string summary:text ingredients:text instructions:text
cooking_time:string created_at:datetime updated_at:datetime
ruby script/generate model Comment
recipe_id:integer body:text created_at:datetime updated_at:datetime
Lets create our databases. I’m using MySQL
sudo mysqladmin create socialrecipe_development
sudo mysqladmin create socialrecipe_test
Lets changed to using database sessions. Now edit config/environment.rb change the Rails Initializer section and uncomment the following line
config.action_controller.session_store = :active_record_store
And add a line at the end of config/environment.rb
ActionController::AbstractRequest.relative_url_root = "/socialrecipe"
What this does is change the Rails application to run starting with a socialrecipe in the first part of the URL. We need this for later but you will need your own unique name (i’m using socialrecipe). So think of one and take note.
Now lets create our development database.
rake db:sessions:create
rake db:migrate
Now lets create our controllers
ruby script/generate controller recipes
ruby script/generate controller comments
Excellent. Now lets change our model definitions so that Recipes can have many comments. Edit app/models/recipe.rb to
class Recipe < ActiveRecord::Base
has_many :comments
validates_presence_of :title, :summary, :ingredients, :instructions
end
And edit models/comment.rb to
class Comment < ActiveRecord::Base
belongs_to :recipe
validates_presence_of :body, :recipe_id
end
Now lets add the controller for the recipe. Edit app/controllers/recipes_controller.rb and change it to
class RecipesController < ApplicationController
def index
@recipes = Recipe.find(:all)
@title = "All recipes"
end
def show
@recipe = Recipe.find(params[:id])
end
def new
@recipe = Recipe.new
end
def edit
@recipe = Recipe.find(params[:id])
end
def create
@recipe = Recipe.new(params[:recipe])
if @recipe.save
flash[:notice] = 'Recipe was successfully created.'
redirect_to :action => 'show', :id => @recipe
else
render :action => "new"
end
end
def update
@recipe = Recipe.find(params[:id])
if @recipe.update_attributes(params[:recipe])
flash[:notice] = 'Recipe was successfully updated.'
redirect_to :action => 'show', :id => @recipe
else
render :action => "edit"
end
end
end
Edit app/controllers/comments_controller.rb and change it to
class CommentsController < ApplicationController
def new
@comment = Comment.new
@comment.recipe_id = params[:recipe_id]
end
def create
@comment = Comment.new(params[:comment])
if @comment.save
flash[:notice] = 'Comment was successfully created.'
redirect_to :controller => 'recipes', :action => 'show', :id => @comment.recipe
else
render_action 'new'
end
end
end
Pretty standard stuff so far creating simple controllers to create, read and update recipes and create comments. Lets setup the views
Add app/views/recipes/index.rhtml with
<h2><%= @title %></h2>
<%@recipes.each do |recipe|%>
<div>
<h3><%= link_to h(recipe.title), :controller => 'recipes', :action => 'show', :id => recipe%></h3>
<p><%=h recipe.summary %></p>
</div>
<%end%>
<br/>
<%= link_to 'New recipe', :controller => 'recipes', :action => 'new' %>
Add app/views/recipes/new.rhtml with
<h1>New recipe</h1>
<%= error_messages_for :recipe %>
<% form_for(:recipe, :url => {:controller => 'recipes', :action => 'create'}) do |f| %>
<dl>
<dt><label for="recipe_title">Title:</label></dt>
<dd><%= f.text_field :title %></dd>
<dt><label for="recipe_summary">Summary:</label></dt>
<dd><%= f.text_area :summary %></dd>
<dt><label for="recipe_ingredients">Ingredients:</label></dt>
<dd><%= f.text_area :ingredients %></dd>
<dt><label for="recipe_instructions">Cooking Instructions:</label></dt>
<dd><%= f.text_area :instructions %></dd>
<dt><label for="recipe_cooking_time">Cooking Time:</label></dt>
<dd><%= f.text_field :cooking_time %> mins</dd>
<dt></dt>
<dd><%= submit_tag "Create" %></dd>
</dl>
<% end %>
<br/>
<%= link_to 'Back', :controller => 'recipes' %>
The use of dl tags for forms is not a facebook thing. It’s just the way I rock it.
Add app/views/recipes/edit.rhtml with
<h1>Editing recipe</h1>
<%= error_messages_for :recipe %>
<% form_for(:recipe,
:url => {:controller =>'recipes', :action => 'update', :id => @recipe}) do |f| %>
<dl>
<dt><label for="recipe_title">Title:</label></dt>
<dd><%= f.text_field :title %></dd>
<dt><label for="recipe_summary">Summary:</label></dt>
<dd><%= f.text_area :summary %></dd>
<dt><label for="recipe_ingredients">Ingredients:</label></dt>
<dd><%= f.text_area :ingredients %></dd>
<dt><label for="recipe_instructions">Cooking Instructions:</label></dt>
<dd><%= f.text_area :instructions %></dd>
<dt><label for="recipe_cooking_time">Cooking Time:</label></dt>
<dd><%= f.text_field :cooking_time %> mins</dd>
<dt></dt>
<dd><%= submit_tag "Update" %></dd>
</dl>
<% end %>
<br/>
<%= link_to 'Show', :controller => 'recipes', :action => 'show', :id =>@recipe %> |
<%= link_to 'Back', :controller => 'recipes' %>
Add app/views/recipes/show.rhtml with
<h1><%=h @recipe.title %></h1>
<p><%=h @recipe.summary %></p>
<h2>Ingredients:</h2>
<p><%=h @recipe.ingredients %></p>
<h2>Instructions:</h2>
<p><%=h @recipe.instructions %></p>
<p><em>Cooking time is around <%=h @recipe.cooking_time %> mins</em></p>
<div id="comments">
<h2>Displaying <%=pluralize(@recipe.comments.size, 'comment')%></h2>
<%= link_to 'New comment', :controller => 'comments', :action => 'new', :recipe_id => @recipe %>
<% @recipe.comments.each do |comment| %>
<div>
<p><%= comment.body %></p>
posted <%= time_ago_in_words(comment.created_at) %> ago
</div>
<%end %>
</div>
<br/>
<%= link_to 'Edit', :controller => 'recipes', :action => 'edit', :id => @recipe %> |
<%= link_to 'Back', :controller => 'recipes' %>
Add app/views/comments/new.rhtml with
<h1>New comment</h1>
<%= error_messages_for :comment %>
<% form_for(:comment, :url =>
{:controller => 'comments', :action => 'create'}) do |f| %>
<dl>
<dt><label for="comment_body">Body Content:</label></dt>
<dd><%= f.text_area :body %></dd>
<dt></dt>
<dd><%= submit_tag "Create" %></dd>
</dl>
<%= f.hidden_field :recipe_id, :value => @comment.recipe_id %>
<% end %>
And lets create a layout at app/views/layouts/index.rhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
<title>Recipes: <%= controller.action_name %></title>
</head>
<body>
<p style="color: green"><%= flash[:notice] %></p>
<%= yield %>
</body>
</html>
and add this line to the app/controllers/application.rb
layout 'index'
change config/routes.rb to have a default route
map.connect '', :controller => "recipes"
and delete index.html from your public directory. That’s it. We now have a simple (and very ugly application). Fire it up with script/server and go to http://localhost:3000/socialrecipe

Lets facebook-it!! First of all we need to install the Ruby Gem RFacebook (this tutorial uses the version 0.6.2. This is a helper for interacting with the Facebook APIs. It will require you install Hpricot but make sure you pick the ruby version not the jruby one.
sudo gem install rfacebook -v 0.6.2
Now you’ll need to log on to facebook (what do you mean you’re not on facebook!) and add the Developer application. Once you have done that press the big “Set Up New Application” button.

Now fill in the following fields
Application Name: Social Recipes (You will need to change this as i have done social recipes) Check the box for Check here to indicate that you have read and agree to the terms of the Facebook Platform. Callback Url: http://localhost:3000/socialrecipe/ (The end of this is the same as your relative_url_root) Canvas Page URL: http://apps.facebook.com/ socialrecipe (The field of this is the same as your relative_url_root) Check Use iframe for now Can your application be added on Facebook? Yes Post-Add URL: http://apps.facebook.com/socialrecipe/ (The end of this is the same as your relative_url_root)
That is all hit save and you should have a page listing your application with an API Key and a Secret. Make a note of your applications API Key and Secret

Now lets edit our rails application. Add the following to your ApplicationController in app/controllers/application.rb
before_filter :require_facebook_login, :set_user
include RFacebook::RailsControllerExtensions
def facebook_api_key
return "ADD YOUR API KEY HERE"
end
def facebook_api_secret
return "ADD YOUR SECRET HERE"
end
def finish_facebook_login
redirect_to :controller => "recipes"
end
def set_user
@current_fb_user_id = fbsession.session_user_id
end
and add the following to your config/environment.rb
require "facebook_rails_controller_extensions"
You’ll see you need to add your own key and own secret to this. The set_user filter is going to set a variable in the controller with the logged in facebook users id. We need this because we are going to store which users created which recipes and comments. To do this we need to add columns to our recipes and comments tables to store the id in. These must be BIGINT if you are using MySQL. Facebook has A LOT of users.
script/generate migration add_fb_user_ids
Now edit db/migrate/004_add_fb_user_ids.rb to:
class AddFbUserIds < ActiveRecord::Migration
def self.up
add_column :recipes, :fb_user_id, :integer
add_column :comments, :fb_user_id, :integer
#if mysql
execute("alter table recipes modify fb_user_id bigint")
execute("alter table comments modify fb_user_id bigint")
end
def self.down
remove_column :recipes, :fb_user_id
remove_column :comments, :fb_user_id
end
end
rake db:migrate
We now need to store the facebook user ids in the tables so we’ll add a hidden field to the forms
Add the following to app/views/recipes/new.rhtml and app/views/comments/new.rhtml just before the end of the form
<%= f.hidden_field :fb_user_id, :value => @current_fb_user_id %>
We are also going to protect the edit recipe to only allow you to edit your own recipes in app/views/recipes/show.rhtml change
<%= link_to 'Edit', :controller => 'recipes', :action => 'edit', :id => @recipe %> |
to
<%is_my_recipe? @recipe do %>
<%= link_to 'Edit', :controller => 'recipes', :action => 'edit', :id => @recipe %> |
<%end%>
and add the following to app/helpers/recipes_helper.rb
def is_my_recipe?(recipe, &block)
yield if recipe.fb_user_id.to_i == @current_fb_user_id.to_i
end
See how we cast the facebook user ids to ints. This makes the match actually possible.
Now that was easy but it’s not very Facebooky. Where’s the social? Lets add some friends stuff.
Edit app/controllers/recipes_controller.rb and add the following actions
def my
@title = "My recipes"
@recipes = Recipe.find_my_recipes(@current_fb_user_id)
render :file => "recipes/index", :use_full_path => true
end
def friends
@title = "Friends recipes"
xml_friends_get = fbsession.friends_get
friend_ids = xml_friends_get.search("//uid").map{|uidNode| uidNode.inner_html.to_i}
@recipes = Recipe.find_friends_recipes(friend_ids)
render :file => "recipes/index", :use_full_path => true
end
Add the following to your Recipe model at app/models/recipe.rb
class << self
def find_my_recipes(fb_user_id)
find(:all, :conditions => ['fb_user_id = ?', fb_user_id])
end
def find_friends_recipes(friends_fb_ids)
find(:all, :conditions => ['fb_user_id IN (?)', friends_fb_ids])
end
end
You can see how we use the facebook API through the rfacebook fbsession.friends_get. This then returns Hpricot XML which we parse to get all the friends of the current user and then look for any Recipes they have created. lets just add these actions to some basic navigation.
Edit app/views/layouts/index.rhtml and include the following just under the body tag
<div id="navigation">
<%= link_to 'All recipes', :controller=>'recipes'%> |
<%= link_to 'My recipes', :controller=>'recipes', :action => 'my'%> |
<%= link_to 'Friends recipes', :controller=>'recipes', :action => 'friends'%>
</div>
We’re done lets start with script/server and navigate to http://localhost:3000/socialrecipe. Woah did you just get redirected to Facebook. Oh yes! It should be asking you to add your new Facebook application now. Tick keep me logged in and press the Log in to button.

You should now get returned to your local application. This is an example of an External Facebook Application. Try creating a new recipe and check it appears in My Recipes.

Try going to http://apps.facebook.com/socialrecipe/. You should see your application inside Facebook. This is an example of an IFrame Facebook Application.

Your application could now be ready to go, you could deploy your application to a server, submit it to the directory and let people add it. But its still not very facebook’y. We shall now go on and look at turning this into a Canvas application. In a canvas FBML application, instead of embedding your application in an IFrame, Facebook is going to make a proxy request to your application and parse the resulting markup. In this markup it can contain the Facebook Markup Language which can display more Facebook like interfaces and other direct interactions but it does limit you in what markup you can use and what you can achieve.
Now because Facebook needs to make a request to a server it must be accessible to Facebook, hence you can’t just run it on your laptop (or you can if you have a static Ip you could route facebook to). But i’m going to use my excellent RailsMachine serving to deploy the application at http://socialrecipe.liverail.net/. So don’t attempt these next steps unless you can also deploy your server to the world.
First of all we need to switch our layouts if we are in the canvas. So change the app/controllers/application.rb
layout 'index'
to
layout :check_fb_layout
def check_fb_layout
if in_facebook_canvas?
"index_fbml"
else
"index"
end
end
This is going to check if the request is in a facebook canvas and if so render a different layout. So add a new layout at app/views/layouts/index_fbml.rhtml
<fb:dashboard>
<fb:header decoration="add_border" icon="false">Liverail Recipes</fb:header>
<fb:create-button
href="<%= url_for(:controller => 'recipes', :action => "new", :only_path => true) %>">
New Recipe</fb:create-button>
</fb:dashboard>
<fb:tabs>
<fb:tab_item
href="http://apps.facebook.com<%= url_for(:controller => 'recipes', :action => "index", :only_path => true) %>"
title="All Recipes"></fb:tab_item>
<fb:tab_item
href="http://apps.facebook.com<%= url_for(:controller => 'recipes', :action => "my", :only_path => true) %>"
title="My Recipes">My Recipes</fb:tab_item>
<fb:tab_item
href="http://apps.facebook.com<%= url_for(:controller => 'recipes', :action => "friends", :only_path => true) %>"
title="Friends Recipes">Friends Recipes</fb:tab_item>
</fb:tabs>
<%unless flash[:notice].blank? %>
<fb:status><%= flash[:notice] %></fb:status>
<%end%>
<%= yield %>
This will add a Facebook navigation tabs. Notice how the fb:create-button_ works fine with a relative URL but the fb:tab_item requires an absolute url with the http://apps.facebook.com, this is one of the many oddities with FBML. Additionaly we must surround the fb:status with a check because it won’t work if you have a blank tag.
We now need to render different markup for our pages.
Add the following to app/controllers/application.rb
def render_facebook(template = default_template_name)
if in_facebook_canvas? #or true
render :action => "#{template}_fbml"
else
render :action => "#{template}"
end
end
You now need to add a call to render_facebook at the end of actions index, show, new, edit for the recipes controller, add a call to render_facebook “index” at the end of actions my, friends for the recipes controller and finally render_facebook at the end of actions new for the comments controller.
Lets create some FBML rendering templates.
First app/views/recipes/index_fbml.rhtml
<fb:header decoration="add_border" icon="false"><%= @title %></fb:header>
<%@recipes.each do |recipe| %>
<div>
<h3><%= link_to h(recipe.title), :controller => 'recipes', :action => 'show', :id => recipe%></h3>
<p>
<fb:profile-pic uid="<%= recipe.fb_user_id %>" size="thumb" />
<fb:name uid="<%= recipe.fb_user_id %>" ifcantsee="anonymous" />
</p>
<p><%=h recipe.summary %></p>
</div>
<%end%>
app/views/recipes/new_fbml.rhtml
<fb:header decoration="add_border" icon="false">New Recipe</fb:header>
<%unless @recipe.errors.blank?%>
<fb:error><%= error_messages_for :recipe %></fb:error>
<%end%>
<% form_for(:recipe, :url => {:controller => 'recipes', :action => 'create'}) do |f| %>
<dl>
<dt><label for="recipe_title">Title:</label></dt>
<dd><%= f.text_field :title %></dd>
<dt><label for="recipe_summary">Summary:</label></dt>
<dd><%= f.text_area :summary %></dd>
<dt><label for="recipe_ingredients">Ingredients:</label></dt>
<dd><%= f.text_area :ingredients %></dd>
<dt><label for="recipe_instructions">Cooking Instructions:</label></dt>
<dd><%= f.text_area :instructions %></dd>
<dt><label for="recipe_cooking_time">Cooking Time:</label></dt>
<dd><%= f.text_field :cooking_time %> mins</dd>
<dt></dt>
<dd><%= submit_tag "Create" %></dd>
</dl>
<%= f.hidden_field :fb_user_id, :value => @current_fb_user_id %>
<% end %>
<br/>
<%= link_to 'Back', :controller => 'recipes' %>
app/views/recipes/edit_fbml.rhtml
<fb:header decoration="add_border" icon="false">Edit Recipe</fb:header>
<%unless @recipe.errors.blank?%>
<fb:error><%= error_messages_for :recipe %></fb:error>
<%end%>
<% form_for(:recipe, :url => {:controller =>'recipes', :action => 'update', :id => @recipe}) do |f| %>
<dl>
<dt><label for="recipe_title">Title:</label></dt>
<dd><%= f.text_field :title %></dd>
<dt><label for="recipe_summary">Summary:</label></dt>
<dd><%= f.text_area :summary %></dd>
<dt><label for="recipe_ingredients">Ingredients:</label></dt>
<dd><%= f.text_area :ingredients %></dd>
<dt><label for="recipe_instructions">Cooking Instructions:</label></dt>
<dd><%= f.text_area :instructions %></dd>
<dt><label for="recipe_cooking_time">Cooking Time:</label></dt>
<dd><%= f.text_field :cooking_time %> mins</dd>
<dt></dt>
<dd><%= submit_tag "Update" %></dd>
</dl>
<% end %>
<br/>
<%= link_to 'Show', :controller => 'recipes', :action => 'show', :id =>@recipe %> |
<%= link_to 'Back', :controller => 'recipes' %>
app/views/recipes/show_fbml.rhtml
<fb:header decoration="add_border" icon="false">
<%=h @recipe.title %>
</fb:header>
<fb:profile-pic uid="<%= @recipe.fb_user_id %>" size="normal" />
<fb:name uid="<%= @recipe.fb_user_id %>" ifcantsee="anonymous" />
<p><%=h @recipe.summary %></p>
<h2>Ingredients:</h2>
<p><%=h @recipe.ingredients %></p>
<h2>Instructions:</h2>
<p><%=h @recipe.instructions %></p>
<p><em>Cooking time is around <%=h @recipe.cooking_time %> mins</em></p>
<div id="comments">
<h2>Displaying <%=pluralize(@recipe.comments.size, 'comment')%></h2>
<%= link_to 'New comment', :controller => 'comments', :action => 'new', :recipe_id => @recipe %>
<% @recipe.comments.each do |comment| %>
<div>
<fb:profile-pic uid="<%= comment.fb_user_id %>" size="thumb" />
<p><%= comment.body %></p>
posted <%= time_ago_in_words(comment.created_at) %>
ago by
<strong>
<fb:name uid="<%= comment.fb_user_id %>" ifcantsee="anonymous" />
</strong>
</div>
<%end %>
</div>
<br/>
<%is_my_recipe? @recipe do %>
<%= link_to 'Edit', :controller => 'recipes', :action => 'edit', :id => @recipe %> |
<%end%>
<%= link_to 'Back', :controller => 'recipes' %>
app/views/comments/new_fbml.rhtml
<fb:header decoration="add_border" icon="false">New Comment</fb:header>
<%unless @comment.errors.blank?%>
<fb:error><%= error_messages_for :comment %></fb:error>
<%end%>
<% form_for(:comment, :url => {:controller => 'comments', :action => 'create'}) do |f| %>
<dl>
<dt><label for="comment_body">Body Content:</label></dt>
<dd><%= f.text_area :body %></dd>
<dt></dt>
<dd><%= submit_tag "Create" %></dd>
</dl>
<%= f.hidden_field :recipe_id, :value => @comment.recipe_id %>
<%= f.hidden_field :fb_user_id, :value => @current_fb_user_id %>
<% end %>
<br/>
<%= link_to 'Back', :controller => 'recipes', :action => 'show', :id => @comment.recipe_id %>
Now i’m all done. I’m deploying my application to socialrecipe.liverail.net using capistrano and their great 5 min app deployment but you use whichever method you do to deploy your application (remember to install the rfacebook gem on your server). Once that is done you need to change the application settings in Facebook. Log on to Facebook and go the Developer application > See my apps > Edit Settings. Now change the Callback URL from http://localhost:3000/socialrecipe/ to http://socialrecipe.liverail.net/socialrecipe/ with your own names of course. Now click the Use FBML radio button and save
Go to http://apps.facebook.com/socialrecipe. Done! Ruby on Rails Facebook application.

It isn’t the best looking but you can style to your heart’s content. Go to here if you want to add my demo application and play it. In the next part of this tutorial we can do some cool stuff with events and profiles.
UPDATE: The second part can be found here
42 Responses to “Tutorial on developing a Facebook platform application with Ruby On Rails”
Sorry, comments are closed for this article.
June 29th, 2007 at 04:58 PM
Great article, have you seen the one that thoughtbot did: http://giantrobots.thoughtbot.com/2007/6/14/fist-in-your-facebook
June 29th, 2007 at 08:41 PM
Great tutorial, been doing a bit of experimenting with it myself lately. Not sure if its any use to you but in my app I’ve created a FacebookUser class, with a handy method called create_from_fbsession, which also creates a friends array of FacebookUsers. So you can do things like…
@current_user = FacebookUser.create_from_fbsession(fbsession)
Then in your view you could do…
Welcome <%= @current_user.name %>, your friends are…
<% @current_user.friends.each do |user| %> <%= user.name %> <% end %>
Here’s the code…
class FacebookUser
end
I hope it displays ok, if not I can email it to you instead.
June 29th, 2007 at 09:37 PM
Yes i’ve done something similar, although your implementation looks better (although i would go with FacebookUser.new(fbsession)). I didn’t want to abstract the implementation too heavily in the tutorial to make it obvious what is going on.
Thoughtbots post is also cool, i hadn’t seen it before but its not quite complete. I very much like this ideaJune 30th, 2007 at 02:32 AM
I’m having a problem when I add the: include RFacebook::RailsControllerExtensions to the application.rb
I get: Status: 500 Internal Server Error Content-Type: text/html
any ideas?
June 30th, 2007 at 06:40 AM
Have you install the rfacebook gem and added require “facebook_rails_controller_extensions” to your environment.rb
July 2nd, 2007 at 03:43 AM
yes on both accounts.
when I run: gem search—local rfacebook I get: rfacebook (0.6.2)
and near the top of my environment.rb, I have this, copying 3 lines:
July 2nd, 2007 at 04:50 AM
my error
July 2nd, 2007 at 04:53 AM
the last like as wrong, you can delete that post
my error this time
July 2nd, 2007 at 07:42 AM
how about the first few lines of your stack trace
July 2nd, 2007 at 06:23 PM
I can’t explain it Stuart, I hit F5 on the page this morning when I woke up and it redirected to facebook to log in, the came back to the page and started working properly. I’ve spent the last 45 minutes to try and recreate the error again but can’t. Even though I couldn’t even get it to work over the last couple days, trying everything. Maybe something propogated, I don’t know. bizarre. Thanks for your help though. I’ll continue on with the tutorial Thanks!
ps. By stack trace do you mean entries from the development.log, or is there a way to get the stack trace while in the interactive debugger (rdebug)?
July 2nd, 2007 at 06:43 PM
I’m not familiar with this syntax: class << self
and I get a runtime error with it in, is this a typo in your tutorial? thanks
July 3rd, 2007 at 04:52 AM
fs: class << self is used in this context to add class methods to the Recipe model. It is one of the few ways to add class methods in Ruby (and do some other devious things I won’t get into). No typo.
July 3rd, 2007 at 04:56 AM
I’ve having the same problem as fs above. I get an 500 -Internal Server Error and the stack trace leads back to require “facebook_rails_controller_extensions”. Does anyone have any idea what that is about?
July 3rd, 2007 at 10:52 AM
Hello,
I have followed your steps, but however I have a problem when I go to http://localhost:3000/socialrecipe before install the rfacebook gem. I have this message in my firefox:
Not Found `/socialrecipe/’ not found.
Do you have any idea?
Thank you
July 3rd, 2007 at 01:25 PM
have you added a default route map.connect ’’, :controller => “recipes”
and added this to the end of the environment.rb ActionController::AbstractRequest.relative_url_root = ”/socialrecipe”
NB When you are integrating with facebook this relativeroute is going to have to be unique for your application
July 3rd, 2007 at 04:30 PM
I have solved my problem (rails dependencies).
July 3rd, 2007 at 08:30 PM
Excellent tutorial, but very frustrating: the code works on my Mac, but not on my Ubuntu slice. I’m using the latest rubygems and I installed the correct rfacebook from scratch, but to no avail. :(
July 6th, 2007 at 10:17 AM
thx Stuart, great tutorial, had few problems like ERROR 100: Invalid parameter (”auth.getSession”, {:auth_token=>”asd″, :v=>”1.0″, :api_key=>”xyz″, :method=>”facebook.auth.getSession”, :sig=>”qwe”}), have solved this issue by using rfacebook-0.6.1 gem, i was using rfacebook-0.6.3 earlier, thx again nice work
July 6th, 2007 at 08:42 PM
I’ve not done the tut but I will set aside a few hours on the weekend to give it a go.
Thanks for this
July 7th, 2007 at 11:48 AM
Brilliant idea Stuart. Thanks for very interesting article. btw. I really enjoyed reading all of your articles. It’s interesting to read ideas, and observations from someone else’s point of view… makes you think more.
July 10th, 2007 at 11:55 AM
hey guys,
i added AbstractRequest.relative_url_root = ”/myapp” in environment.rb file, but when i run the url , http://localhost:3000/myapp/accounts/login iam getting the login page but its not showing any css stuff and images, in the development log iam getting, ActionController::RoutingError (no route found to match ”/stylesheets/login.css” with {:method=>:get})
any suggestions?
thx in advance
July 10th, 2007 at 03:39 PM
Yes i know this problem. with the relative root is added to the start of all urls even javascript and css ones!!. The only solution I know is to create a directory ‘myapp’ in your case under the public directory and then to copy the stylesheets and css directorys under myapp.
July 11th, 2007 at 07:00 AM
thx Stuart, actually i had solved the problem same way u have suggested but not sure is this a correct way?
July 11th, 2007 at 08:09 PM
Hi Stuart – rockin’ tutorial. Keep ‘em coming!
I’m stuck with the following (appears when clicking on ‘Friends Recipes’ in or out of an iFrame);
TypeError in RecipesController#friends can't dup NilClass RAILS_ROOT: script/../config/.. Application Trace | Framework Trace | Full Trace /usr/local/lib/ruby/gems/1.8/gems/rfacebook-0.6.3/lib/facebook_session.rb:157:in `dup' /usr/local/lib/ruby/gems/1.8/gems/rfacebook-0.6.3/lib/facebook_session.rb:157:in `call_method' /usr/local/lib/ruby/gems/1.8/gems/rfacebook-0.6.3/lib/facebook_session.rb:138:in `method_missing' app/controllers/recipes_controller.rb:53:in `friends'July 12th, 2007 at 06:13 AM
i was working on your tutorial and got every thing on good way every data is going to database and retrieving of data are also fine but when i didn’t filled any data while creating new recipe and clicked on the save button and was expecting error message i got this error
Errors while loading page from application Runtime errors:
fb:error: You must specify a message with an fb:message tag or a message attribute
There are still a few kinks Facebook and the makers of social item are trying to iron out. We appreciate your patience as we try to fix these issues. Your problem has been logged – if it persists, please come back in a few days. Thanks!
please help me to proceed and tell me the exact problem where i went wrong
Thanks and regard
July 13th, 2007 at 10:11 PM
Just to follow-up my problem with ‘dup NilClass’ – it looks like there’s a problem with the rfacebook gem, and it’s detailed here;
http://facebook.jdg.net/forums/RFacebook-Help/topics/Anybody-else-getting-can-t-dup-NilClass-
I still haven’t worked out how to apply the patch though!
July 16th, 2007 at 07:39 AM
Great article. You have done a mistake is that you have written “and finally render_facebook at the end of actions new for the recipes controller.” but it should be “and finally render_facebook at the end of actions new for the comments controller.”
Thanks
July 16th, 2007 at 04:06 PM
Great post. Thanks for putting it up.
Is it possible for an existing Rails app to also be a Facebook app int hat it can be served through a browser or through Facebook? Mostly due to this:
:require_facebook_login
It doesn’t sound like it is possible, even if you take out an user related functions. I’m new to Rails so I may be missing something obvious.
July 16th, 2007 at 04:35 PM
I think i did this right but when i get to face book i get “Received HTTP error code 404 while loading” any ideas?
July 16th, 2007 at 04:45 PM
Yes it is possible to add a normal Rails application to also be a Facebook application. Have a look at thoughtbots post which is on that exact thing http://giantrobots.thoughtbot.com/2007/6/14/fist-in-your-facebook
July 16th, 2007 at 06:55 PM
Thanks for the quick reply. I see now you can do a
if facebook?
call which is pretty much what I am looking for. It still doesn’t look like cross-user interaction is possible, wherein someone can log into my app either through facebook or through a regular web browser. Maybe an extension to my :require_login is possible. I’ll work on it.
Thanks for your help.
July 17th, 2007 at 01:44 PM
I am using Instant Rails and I get stuck on creating the database “sudo mysqladmin create social_recipe development” and i get the error ”’sudo’, is not recognized as an internal or external command, operable program or batch file” I have no idea what to do. Help would be great. Thanks
July 17th, 2007 at 01:47 PM
and i know its “socialrecipe_development” instead of “social_recipe development”...that was just a typo
July 18th, 2007 at 03:20 PM
Thanks Stuart – excellent tutorial. I had the same problems as fs above and sorted them by uninstalling version 0.6.4 of rfacebook and replacing with 0.6.4 – ie
gem uninstall -v 0.6.4 rfacebook gem install -v 0.6.2 rfacebook
Hope this helps anyone else with these problems.
July 23rd, 2007 at 03:25 AM
I’m using the latest version of rfacebook (1.6.7) and was getting nill errors unrelated to any other posts here.
This is documented in the trac @ http://rubyforge.org/tracker/index.php?func=detail&aid=12381&group_id=3607&atid=13796
I changed the particular lines in the code on my local machine and it works fine now.
July 24th, 2007 at 02:19 PM
This is a great article. Does anyone have any further information on how to make rails sessions work with Facebook. I have read on a different site that Facebook creates a new session with every request, but you can set up your configuration to store the Facebook session id in the sessions database for rails. So far I have been unable to get this to work. Any ideas?
Thanks, Ron
The article has you add the following to the end of your enviroments.rb
ActionController::Base.session_options[‘session_key’] = ‘fb_sig_session_key’
class CGI class Session class ActiveRecordStore def initialize(session, option = nil) session_id = session.session_id unless
session = ActiveRecord::Base.silence {@session_class.find_by_session_id(session_id) }session =@session_class.new(:session_id => session_id, :data => {}) end end end end endJuly 26th, 2007 at 03:01 PM
Great tutorial!
But I get an error ( NoMethodError in RecipesController#index ) with the line: before_filter :require_facebook_login, :set_user
I think these are the last three lines of the stack trace:
/usr/local/lib/ruby/gems/1.8/gems/rfacebook-0.6.8/lib/facebook_rails_controller_extensions.rb:37:in `fbparams’ /usr/local/lib/ruby/gems/1.8/gems/rfacebook-0.6.8/lib/facebook_rails_controller_extensions.rb:60:in `fbsession’ /usr/local/lib/ruby/gems/1.8/gems/rfacebook-0.6.8/lib/facebook_rails_controller_extensions.rb:130:in `require_facebook_login’
The issues seems to be around the facebook gem log-in, but I’m pretty sure I’ve added the neccassary include in environment.rb correctly.
July 26th, 2007 at 10:37 PM
I fixed my issue by downgrading the rfacebook gem to version 0.6.3
July 27th, 2007 at 04:58 PM
I have a couple ideas that I’d like to get onto Facebook, but I need help. Anybody available for freelance work? I don’t have a huge budget, but perhaps we can work something out that would make it a win-win.
Write me “Chazz Scarfiotti” on Facebook!
Cheers,
Chazz
July 28th, 2007 at 04:24 PM
$ gem install hpricot 3. hpricot 0.6 (ruby) $ gem install rfacebook Successfully installed rfacebook-0.7.0 $ vi config/environment.rb $ vi app/controllers/application.rbApplication error Rails application failed to start properly
$ gem uninstall rfacebook 5. All versions gem install -v 0.6.3 rfacebookApplication error Rails application failed to start properly
Any ideas why this isn’t working? Same problem “fs” and others.
July 28th, 2007 at 04:25 PM
Post format doesn’t allow code tag, so reposting…
$ gem install hpricot 3. hpricot 0.6 (ruby)
$ gem install rfacebook Successfully installed rfacebook-0.7.0
$ vi config/environment.rb $ vi app/controllers/application.rb
Application error Rails application failed to start properly
$ gem uninstall rfacebook 5. All versions
$ gem install -v 0.6.3 rfacebook
Application error Rails application failed to start properly
Any ideas why this isn’t working? Same problem “fs” and others.
July 29th, 2007 at 04:15 AM
@Rosk—sudo is a Mac / Unix thing; you don’t need to do that. Create your database using PHPmyAdmin directly.