Nov 252009
 
WARNING: These instructions are for Facebook version 1 (not Facebooker2). Since last year, I have moved toward using a different gem for this due to Facebooker’s lack of documentation. Working on a new blog post detailing that.

So you want to write a Facebook app written in Rails? Well, the good news is that it works. The bad news is that out of the box Facebook didn’t quite design their platform to work with some of the core concepts (namely, REST) of Rails.

You need to use a great plug-in called Facebooker. Here is a quick set-up guide to help you along, with some tips and pitfalls.

1. Install these two gems

sudo gem install facebooker htmlentities

2. Install the plugin

script/plugin install git://github.com/mmangino/facebooker.git

3. add this to your environment.rb file

 config.action_controller.allow_forgery_protection = false
 config.gem “htmlentities”
 config.gem “facebooker”

4. configure your facebooker.yml. See the Facebook developer site for your site’s API key and secret. You’ll also put in your canvas path here.

In facebooker.yml, your canvas_page_name is the part first part after apps.facebook.com/ where your users will use your app. You do not need a leading or trailing slash. (In Facebook developer, go to Edit Settings > Canvas > “Canvas Page URL”).

Your callback_url is the URL name where you will operate (include http:// ) and under your facebooker.yml settings is called “Canvas Callback URL.” You don’t need a trailing slash here either. Your users won’t see this URL, because only Facebook will talk to this domain. Therefore, you can safely have it be a subdomain.

development:
api_key: XXXXX
secret_key: YYYYYYY
canvas_page_name: mygreatapp
callback_url: http://www.yourdomain.com
pretty_errors: true
set_asset_host_to_callback_url: true
tunnel:
  public_host_username: your_username
  public_host: the_tunnel_host
  public_port: 3000
  local_port: 3000
  server_alive_interval: 0

5. I found that your app has to be developed live (or at least live on a dev server). The only other way to develop would be to re-route the network where your local is to be the end-point for the the call from Facebook to your app.

I found that doing it this way was a pain, so I devised this lightweight hack to let you push all your changes up to your github account, then add a post-receive hook in your github repo to trigger your development environment to update itself for every commit you make. Tedious, I know, but effective. (Optional)

 # add this to your ApplicationController
 def github_pull
  output = “Pulling from github…”
  output << `/opt/local/bin/git pull`
  output << `touch tmp/restart.txt`
  render :text => “”
 end
// add this to your routes.rb file
 git hub pull route
 map.connect ‘/github_pull’, :controller => “application”, :action => “github_pull”

7. Create a facebook_controller.rb in the app/controllers folder. I highly recommend this for one important reason: Your app might have parts of it that you don’t want bypass the Facebook authentication (for example, you go to create some kind of an AdminController). All other controllers (the ones your users interact with) should be inherited from the FacebookController (instead of the ApplicationController). That way, you’ll get to keep the Facebook logic inside of this FacebookController. If you have a controller you want outside of the Facebook part of your app, you can make it inherit from the ApplicationController as you normally would.

class FacebookController < ApplicationController
  helper :all
  layout “application”
  before_filter :current_user

  protect_from_forgery
  ensure_authenticated_to_facebook
  ensure_application_is_installed_by_facebook_user
  filter_parameter_logging :fb_sig_friends, :password
  
  def current_user
   @current_user ||= User.find_or_create_by_facebook_uid(params[:fb_sig_user])
  end
end

8. Map your root route in routes.rb (you have to figure that out yourself based on what you want your canvas page to be).

9. Configure your database.yml, .gitignore, etc.

From here, you can start generating your models. You’ll notice that I added to the FacebookController the assumption that you have a User model with a facebook_uid attribute, so go ahead and generate one now if you haven’t already.

script/generate facebook_scaffold User facebook_uid:integer

Note: You cannot use the normal scaffold generator. That’s because your
respond_to block in your controllers must have a format line for fbml. This suspends the normal rules of REST and allows all actions to be POST actions. If you don’t do this, you get:

406 Not Acceptable

Your controllers should look like this:

  respond_to do |format|
   format.fbml
  end

And your templates should end with “.fbml.erb”. You can just go ahead and rip out those format.html and format.xml calls – unless you have some funky kind of hybrid app that works in & out of Facebook, you don’t need them.

=== TIPS ===

You can access any of the settings in config/facebook.yml but using the FACEBOOKER global hash, as in:

FACEBOOKER[:callback_url]
FACEBOOKER[:canvas_page_name]

If you are using Rails with Passenger and you get this error:
Undefined method rewind and rails 2.3.3

– update passenger to the latest version
sudo gem update passenger
sudo passenger-install-apache2-module

 Posted by at 1:35 pm  Tagged with:
Nov 192009
 

This is a work in progress.

Rails Version Release month
2.0.0 Dec 2007
2.0.1 Dec 2007
2.0.2 Dec 2007
2.1.0 May 2008
2.1.1 Sept 2008
2.1.2 Oct 2008
2.2.2 Nov 2008
2.3.2 March 09
2.3.3 July 2009
2.3.4 Sept 2009
2.3.5 recently
 Posted by at 3:38 pm
Nov 162009
 

strftime() turns a Date or DateTime into nicely formatted output. The following table shows the code you can use to create a nicely formatted date

>> x = DateTime.new(2009,9,5,15,45,50)
=> Sat, 05 Sep 2009 15:45:50 +0000

The default is %F which is the same as writing this.

>> x.strftime(‘%F’)
=> “2009-09-05”

Current timestamp with milliseconds.

#{DateTime.now.strftime(‘%Y-%m-%d %H:%M:%S + %L’)}

Continue reading »

 Posted by at 2:57 pm

Git primer

 Uncategorized  No Responses »
Nov 142009
 

The is the very bare-bones basics of git.

First, I am staring by assuming that someone else has already setup a git repository on github. If it is a private repository, the author must grant you access to that repository by adding your github account name to the project.

Once this is done, you will see this project under “Your repositories.”

Every git project has a git URL associated with it. You will find this URL on the project’s page. Continue reading »

 Posted by at 10:22 pm
Nov 082009
 

If you are getting this error after a Rails 2.3.3 update

undefined method `rewind’ for #<TCPSocket:0x3631e58>

Try updating your version of passenger:

sudo gem update passenger

If you see this after a Rails 2.3.3 update, you need to update Phusion passenger update (I was upgrading from Passenger 2.1.3)

sudo gem update passenger
sudo passenger-install-apache2-module
 Posted by at 1:34 pm
Nov 022009
 

Getting RSS feeds to work right; Firefox error message “This XML file does not appear to have any style information associated with it. The document tree is shown below.”

I came across an interesting thing about this particular error message in Firefox, which appears when you try to look at an RSS (or XML, I’ll get to that) feed that doesn’t work right.

The error you see in Firefox is a warning message at the top of the screen which reads:

“This XML file does not appear to have any style information associated with it. The document tree is shown below.”

You need to note that basically Firefox isn’t recognizing this as a valid RSS. There are two things you should check when debugging this problem:

1. the Content-Type response page must be set to application/rss+xml. If it is just application/xml, you’ll get this error in Firefox.

2. While all RSS is by definition XML (that is, the structure of the document returned by the server is XML), not all XML is RSS. This might be confusing to people who assume that RSS can just render any kind of XML document.

Although RSS uses XML, it requires specific elements, like the <channel> and <item> elements. See this link for the complete specification.

Your output should look something roughly like this. Note that the <title>, <link> and first <description> elements refer to the <channel> (as they are the direct descendant of the <channel>), where as the second <description> element refers to the <item>.

<?xml version=”1.0″ encoding=”UTF-8″?>
<rss version=”2.0″>
 <channel>
  <title>title for my channel</title>
  <link>http://www.example.com</link>
  <description>this description applies to my channel</description>
  <item>
   <description>description for this item</description>
  </item>
 </channel>
</rss>
 Posted by at 10:46 am