RFacebook on Rails

Another update - wow these are coming fast now. This weekend I finished up another fairly major upgrade to RFacebook: a true Rails plugin. Features include:

  • fbsession and fbparams in both controllers and views
  • automatic URL rewriting when you are in the Canvas (all URLs made relative to apps.facebook.com)
  • acts_as_facebook_user
  • a unique debug panel to help with common issues
  • configuration via facebook.yml file
  • easy SSH tunneling so that you can develop from your local machine
  • no need to keep the plugin up to date - it stays up to date with the Gem

You can get all the information and documentation here: rfacebook.rubyforge.org.

Hope you enjoy the new features.

25 Responses to “RFacebook on Rails”

  1. Ben Says:

    Just thought I’d say thanks for the work you’re doing here, much appreciated Matt :-)

  2. Chris T Says:

    Am I missing something? The plugin files seem to be just single line require statements.

  3. Matt Says:

    Ben - you’re welcome!

    Chris- nope, you’re not missing anything. The plugin simply includes files from the Gem. This way, you simply update the Gem, and your plugin gets updated as well. You’ll need to make sure you’re using the RFacebook Gem >= 0.8.0 though.

  4. Chris T Says:

    OK. I was using 0.7.1. Plus I froze the gem inside vendor (I’ve got a number of separate severs doing the backend of the end, and plugins make it somewhat easier.)

    Any reason why not just package the code as a plugin, rather than a plugin which requires the gem?

  5. Matt Says:

    Plugins don’t have dependency tracking, and it isn’t quite as easy to keep them up to date (or roll them back when the newer version has issues). With the bulk of the code inside the gem, I don’t have to worry about a new gem breaking the old plugin or vice-versa.

    This is good feedback though. I think the simplicity of doing a “gem update” is a win, but you are correct that frozen gems kind of lose this benefit. If a majority of people really dislike that the gem and plugin are updated in lock-step, I will consider separating them. Would a self-update rake task (to update the gem and freeze it) be any help?

  6. Chris T Says:

    Gem update is good if you’re working off a single server, but once you start to grow it somewhat loses its appeal. And once you’re in production, as I am, very much so.

    Hence the common practice of freezing rails.

    It’s not just the question of updating all the gems simultaneously, it’s also that in production (IMHO) you just don’t want to do a blanket gem update, and probably don’t want to update any gems unless (a) you really need the updated functionality, or (b) there’s a security update, and even then, it’d be nicer to freeze them on your dev box (and perhaps staging server too), and build the updated functionality into your test suite.

    I take the point about dependency tracking, I think we’re only talking about hpricot, no?
    It’s just my $0.02, but I’m much happier to have all the code in my vendor directory — though I may be the only one…

  7. Matt Says:

    I can definitely understand that blanket Gem updates are something that you don’t want to do in production. RFacebook is intended to be a production-grade gem and plugin, so this warrants another look.

    I’m not really familiar with your particular deployment process, but isn’t a blanket deployment of a plugin just as dangerous? The effects of a new plugin or a new Gem shouldn’t manifest themselves until you restart all your production servers anyway.

    Also, it seems that you could do “gem update” on your staging box, and then “rake gems:freeze” and deploy if all goes well. Does this accomplish the same as updating the plugin and then deploying?

    Thanks again for your feedback Chris. By the way, I checked out your site - very cool. I’m going to forward it on to my dad, who is really into classic cars.

  8. Chris T Says:

    Glad you like the site — it’s a work in progress, but then aren’t they all.

    I take your point about updating the plugins, but I try to make sure I understand how it works before deploying (somehow seems easier with a plugin). Also, perhaps it’s just psychological, but it somehow feels better having code in the confines of vendor than in something like /usr. It’s also (I seem to remember) easier to write tests for plugins (see below) and easier to patch the code (particulalrly if you’re using piston).

    Also can I make a plea for you to add some tests (I’ll happily help once I’ve understood how it works, though I’m not the best test coder) — it’ll add confidence, perhaps find some bugs, and act as a way of documenting usage (see technoweenie’s plugins for ones which are solely documented by their tests).

    Phew! If you want to contact me off site you can email me at chris dot taggart at pushrodmedia dot co dot uk or I’m on AIM under chrismtaggart.

    Cheers
    Chris
    p.s. Can you still use the gem without the plugin — I’m getting an error:
    (eval):3:in ‘alias_method’: undefined method `url_for’ for module `RFacebook::RailsControllerExtensions’

  9. Matt Says:

    Yes, you can still use the gem without the plugin. That is a bug that it didn’t work out of the box for you - this is fixed in 0.8.1.

    With regards to tests: the hard part about testing this particular plugin is the dependence on being run from inside Facebook. Beyond just testing the Facebook Session (which has been vetted and basically unchanged for the last 3 months), there isn’t much that a battery of tests can do from the commandline. I’m hoping that the new debug panel is a good solution for this problem. Using the debug panel should help to discover problems up front. I’m hoping to extend this further in the next releases.

  10. Chris T Says:

    I see your point re the tests, but I’m wondering whether it can be done using mocks (I’m a big fan of Mocha). One thing that’s delaying me re the tests is finding a good guide to the raw REST data, i.e. what a query and response cycle looks like. All the docs seem to concentrate on how the API behaves when using one of the wrappers. Any pointers?

  11. Matt Says:

    Not entirely sure I understand the question, but the docs like facebook.users.getInfo basically describe the parameters that go into every call (api_key, session_key, call_id, sig, v, and format), and the parameters that are specific to each call (in this case, uids and fields). When using RFacebook, you are only providing the specific parameters - the library does the rest behind-the-scenes.

    If you want to know how the behind-the-scenes stuff works, you should read the section on authentication. The stuff you really want is near the bottom, regarding how the request should be “signed” using you API secret and MD5 hash. In the RFacebook code, you can take a look at call_method, generate_signature, and post_request. The call_method function does the entire request-response cycle for a Facebook API call.

  12. Chris T Says:

    Think I’d looked at the authentication section early on without properly digesting it. Had another read and is now starting to make sense. Thanks

  13. James Says:

    Hey Matt, I’m running into issues right away — I’ve got the gem and plugin installed, and placed the before filter for requiring a facebook login. However, I’m getting “stack level too deep” errors, similar to what this poster is seeing:

    http://facebook.jdg.net/forums/RFacebook-Help/topics/Stack-level-too-deep

    Any ideas? The guy on the forum seemed to make it work when rolling back to an older version. Have you seen these issues before?

  14. Matt Says:

    Yea, there was a bug in gems 0.8.0 to 0.8.3. Try updating to 0.8.4, that should fix it. My apologies.

  15. Dave Troy Says:

    It seems that RFacebook’s redefinition of url_for conflicts with another url_for method somewhere in Rails.

    I’m using this construct in a helper:
    link_to_remote ‘Login’, :url => ‘/user/login’, :update => ‘dialogbox’

    That seems to call a url_for method which gets clobbered by your monkeypatch.

    (eval):7:in `[]=’
    (eval):7:in `url_for’
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_view/helpers/url_helper.rb:27:in `send’
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_view/helpers/url_helper.rb:27:in `url_for’
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_view/helpers/prototype_helper.rb:242:in `remote_function’
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_view/helpers/prototype_helper.rb:133:in `link_to_remote’

    Any suggestions and/or fixes appreciated. Thanks!

  16. Matt Says:

    Yea, the class_eval is an unfortunate necessity in order to override the Rails url_for and still have access to the original. What version of the RFacebook gem are you running? Those eval line numbers look out of date.

    I think that there are definitely some Rails AJAX issues that RFacebook needs to overcome. Please file a bug if the latest gem (0.8.6 as of this writing) does not fix this particular instance for you.

  17. Dave Troy Says:

    I upgraded to 0.8.6 and that dealt with my previous issue with url_for — thanks.

    I am now having an issue with link_to_remote not including the Facebook URL info in its ajax urls. Strangely it still works, at least some of the time, but then breaks after a while.

    Anyway is there a workaround I can use to get link_to_remote to work, or is this something that can be readily fixed in the gem? Thanks!

  18. Matt Says:

    Currently, I don’t have a workaround for link_to_remote. I plan on having another update sometime this week or weekend, so I may address it then. If you come up with a patch before I do, please post it to:

    http://rubyforge.org/tracker/?func=add&group_id=3607&atid=13798

  19. Navneet Aron Says:

    I’m getting the following error while trying to build a demo facebook app in rails. I’ve Rfacebook gem version 0.8.7 .

    ActionView::TemplateError (RFacebook::Rails::ControllerExtensions::APICallbackNeededStandardError) on line #3 of app/views/l$1:
    2: Liverail Recipes
    3: ‘recipes’, :action => “new”, :o nly_path => true %>”>
    4: New Recipe
    5:
    6:

    I’ll appreciate any help, pointers..
    Thanks
    Navneet

  20. Matt Says:

    Did you set up your facebook.yml file? Be sure to type “rake facebook:setup” on the commandline, and then edit facebook.yml to have your own API key, secret, canvas path, and callback path. If you follow the instructions at http://rfacebook.rubyforge.org, then this error shouldn’t come up.

    You should also check out http://facebook.jdg.net, that is where most developers using RFacebook hang out.

  21. Ryan Thompson Says:

    gem is rfacebook (0.8.8)

    After I install the sample app and plugin..

    [log truncated]

    I know the api key, session key, app setup are good because they\’ve worked in the past when I just used the gem (earlier versions tho)

    Any help is appreciated :-)

  22. Ryan Thompson Says:

    sorry about the long lines :-|

  23. Ryan Thompson Says:

    Turns out I just needed to add a default route…

    map.connect ‘’, :controller => “iframe”, :action => ‘index’

    Thanks for all the great work so far Matt.

  24. Mark Says:

    Can you help on a project?

  25. Matt Says:

    @Mark

    Sorry, I’ve been pretty busy lately. You might want to check out http://jypsie.com/RFacebook for help with your app.

Leave a Reply