<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <title>Liverail - Home</title>
  <id>tag:www.liverail.net,2008:mephisto/</id>
  <generator version="0.8.0" uri="http://mephistoblog.com">Mephisto Drax</generator>
  <link href="http://www.liverail.net/feed/atom.xml" rel="self" type="application/atom+xml"/>
  <link href="http://www.liverail.net/" rel="alternate" type="text/html"/>
  <updated>2008-02-23T11:08:27Z</updated>
  <entry xml:base="http://www.liverail.net/">
    <author>
      <name>stuarteccles</name>
    </author>
    <id>tag:www.liverail.net,2008-02-23:3914</id>
    <published>2008-02-23T11:01:00Z</published>
    <updated>2008-02-23T11:08:27Z</updated>
    <category term="RailsDAV"/>
    <category term="RubyOnRails"/>
    <category term="railsdav"/>
    <category term="ruby on rails"/>
    <link href="http://www.liverail.net/articles/2008/2/23/railsdav-now-up-for-rails-2-0-2" rel="alternate" type="text/html"/>
    <title>RailsDAV now up for Rails 2.0.2</title>
<content type="html">
            &lt;p&gt;Hi all,&lt;/p&gt;


	&lt;p&gt;The RailsDAV plugin for integrating WebDAV controllers into your Rails application is now compatible with Rails 2.0.2. I&#8217;m doing a complete re-write to make RailsDAV easier to use and work with merb as well, but it&#8217;s slow going.&lt;/p&gt;


	&lt;p&gt;You can install RailsDAV with&lt;/p&gt;


&lt;pre&gt;
&lt;code class=&quot;console&quot;&gt;
ruby script/plugin install http://svn.liverail.net/svn/plugins/railsdav
&lt;/code&gt;
&lt;/pre&gt;
          </content>  </entry>
  <entry xml:base="http://www.liverail.net/">
    <author>
      <name>stuarteccles</name>
    </author>
    <id>tag:www.liverail.net,2007-10-03:2701</id>
    <published>2007-10-03T11:00:00Z</published>
    <updated>2007-10-03T11:07:18Z</updated>
    <category term="Flex"/>
    <category term="adobe"/>
    <category term="amp ,adobe media player"/>
    <link href="http://www.liverail.net/articles/2007/10/3/adobe-media-player" rel="alternate" type="text/html"/>
    <title>Adobe Media Player</title>
<content type="html">
            &lt;blockquote&gt;
		&lt;p&gt;It&#8217;s starting to look at lot like Christmas&#8230; well for Flash developers anyhow&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;That comes from &lt;a href=&quot;http://www.danieltodd.com/&quot;&gt;Daniel Todd&lt;/a&gt; and I think he&#8217;s referring to the amount of new goodies Adobe released in the last couple of days. We had the &lt;a href=&quot;http://labs.adobe.com/downloads/air.html&quot;&gt;&lt;span class=&quot;caps&quot;&gt;AIR&lt;/span&gt; Beta 2&lt;/a&gt; &lt;a href=&quot;http://labs.adobe.com/technologies/flex/&quot;&gt;Flex 3 Beta 2&lt;/a&gt; &lt;a href=&quot;http://labs.adobe.com/wiki/index.php/Thermo&quot;&gt;Thermo&lt;/a&gt; and &lt;a href=&quot;http://labs.adobe.com/wiki/index.php/Media_Player&quot;&gt;Adobe Media Player&lt;/a&gt;. Thankfully the new &lt;span class=&quot;caps&quot;&gt;AIR&lt;/span&gt; beta fixes my favorite &lt;del&gt;making &lt;span class=&quot;caps&quot;&gt;AIR&lt;/span&gt; useless&lt;/del&gt; bug &lt;a href=&quot;http://coenraets.org/blog/2007/06/sqlqueue-chaining-asynchronous-sql-statements-using-the-air-database-access-api/&quot;&gt;synchronous database access&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;But its Adobe Media Player I&#8217;m loving at the moment. It&#8217;s an &lt;span class=&quot;caps&quot;&gt;AIR&lt;/span&gt; app and it needs the new beta runtime and for those who know nothing about it, basically it&#8217;s a cross between iTunes and &lt;a href=&quot;http://www.joost.com/&quot;&gt;Joost&lt;/a&gt; but for Flash video. With a modified &lt;span class=&quot;caps&quot;&gt;RSS&lt;/span&gt; feed video suppliers can create a channel of Flash video for people to watch, favorite and share. It downloads the video so you can watch it offline as well.&lt;/p&gt;


	&lt;p&gt;&lt;img src=&quot;http://www.liverail.net/assets/2007/10/3/Picture_2_thumb.png&quot; alt=&quot;Adobe Media Player Interface&quot; /&gt;&lt;/p&gt;


	&lt;p&gt;So far, so iTunes. But a channel feed can also include branding elements to give every channel a different look. But not too special right. It&#8217;s the future of &lt;span class=&quot;caps&quot;&gt;AMP&lt;/span&gt; that&#8217;s exciting, the ability to embed advertising, pre-rollers, post-rollers, interactive elements. The &lt;em&gt;Buy that shirt the guy in the video has&lt;/em&gt; element which makes &lt;span class=&quot;caps&quot;&gt;AMP&lt;/span&gt; attractive for content producers and distributers.&lt;/p&gt;


	&lt;p&gt;&lt;img src=&quot;http://www.liverail.net/assets/2007/10/3/Picture_1_thumb.png&quot; alt=&quot;Adobe Media Player Branded Channel&quot; /&gt;&lt;/p&gt;


	&lt;p&gt;But a more interesting future for &lt;span class=&quot;caps&quot;&gt;AMP&lt;/span&gt; is allowing companies to white-label it, skinning and modifying the player to create their own iTunes/&lt;a href=&quot;http://www.bbc.co.uk/iplayerbeta/&quot;&gt;&lt;span class=&quot;caps&quot;&gt;BBC&lt;/span&gt; iPlayer&lt;/a&gt; (without the &lt;span class=&quot;caps&quot;&gt;DRM&lt;/span&gt; and with the Mac!). A great idea, I&#8217;m just surprised Adobe is there first. Normally I would expect to see this kind of thing coming out of a company like &lt;a href=&quot;http://www.brightcove.com/&quot;&gt;Brightcove&lt;/a&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.liverail.net/">
    <author>
      <name>stuarteccles</name>
    </author>
    <id>tag:www.liverail.net,2007-09-19:2613</id>
    <published>2007-09-19T14:23:00Z</published>
    <updated>2008-02-14T17:58:51Z</updated>
    <category term="RubyOnRails"/>
    <category term="presenter"/>
    <category term="RailsConfEurope"/>
    <category term="railsconfeurope"/>
    <category term="thoughtworks"/>
    <link href="http://www.liverail.net/articles/2007/9/19/railsconf-europe-wednesday-sessions-3" rel="alternate" type="text/html"/>
    <title>RailsConf Europe - Wednesday Sessions - 3</title>
<content type="html">
            &lt;p&gt;This is my last session of the day as i&#8217;ll have to run about by 5 and dive in a taxi to catch my flight.&lt;/p&gt;


	&lt;h3&gt;Extending Rails to Use the Presenter Pattern&lt;/h3&gt;


	&lt;p&gt;The &lt;a href=&quot;http://conferences.oreillynet.com/cs/railseurope2007/view/e_sess/13941&quot;&gt;Extending Rails to Use the Presenter Pattern&lt;/a&gt; could be re-titled talking Ruby On Rails beyond &lt;span class=&quot;caps&quot;&gt;MVC&lt;/span&gt; by Jay Fields of ThoughtWorks.&lt;/p&gt;


	&lt;p&gt;He lost me quickly in ThoughtWorks-Speak, referencing everything in the ideas of Enterprise patterns. It&#8217;s Martin Fowler world. It&#8217;s tough to talk to people who may not be fully versed in your lingo and get the subtle references.&lt;/p&gt;


	&lt;p&gt;I&#8217;m gathering some ideas that Presenters are a way to make testing controllers easier and view testing isn&#8217;t really worth it (which I&#8217;ll agree with).&lt;/p&gt;


	&lt;p&gt;I&#8217;ll suggest checking out &#8220;Jay&#8217;s blog&#8217;:http://blog.jayfields.com/ if you are interested in these things as I didn&#8217;t get much out of this at all, Jay doesn&#8217;t even like the pattern. It was only about 25 minutes as well&#8230;. The person behind me just said &#8220;I&#8217;m feeling a bit swissed&#8230;..&#8221; and next to me &#8220;Possibly one of the most over-hyped talks here&#8221;&lt;/p&gt;


	&lt;p&gt;&lt;a href=&quot;http://www.liverail.net/assets/2007/9/19/19092007069.jpg&quot;&gt;&lt;img src=&quot;http://www.liverail.net/assets/2007/9/19/19092007069_thumb.jpg&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.liverail.net/">
    <author>
      <name>stuarteccles</name>
    </author>
    <id>tag:www.liverail.net,2007-09-19:2610</id>
    <published>2007-09-19T13:24:00Z</published>
    <updated>2008-02-14T17:59:31Z</updated>
    <category term="RubyOnRails"/>
    <category term="liquid"/>
    <category term="RailsConfEurope"/>
    <category term="railsconfeurope"/>
    <category term="shopify"/>
    <category term="startup"/>
    <category term="web2.0"/>
    <link href="http://www.liverail.net/articles/2007/9/19/railsconf-europe-wednesday-sessions-2" rel="alternate" type="text/html"/>
    <title>RailsConf Europe - Wednesday Sessions - 2</title>
<content type="html">
            &lt;p&gt;First of all, some of the presentation downloads for RailsConf Europe have started appearing on the O&#8217;Reilly site &lt;a href=&quot;http://conferences.oreillynet.com/pub/w/61/presentations.html&quot;&gt;here&lt;/a&gt;, so please run along and grab them. Nothing to see here.&lt;/p&gt;


	&lt;p&gt;Well ok, i&#8217;ll continue live-blogging from the afternoon sessions but I have a plane to catch soon :-)&lt;/p&gt;


	&lt;h3&gt;Development Case Study: MindMeister&lt;/h3&gt;


	&lt;p&gt;I&#8217;ve chosen the lest technical session because sometime the anecdote, the story, is more useful than the code. &lt;a href=&quot;http://conferences.oreillynet.com/cs/railseurope2007/view/e_sess/14216&quot;&gt;Development Case Study: MindMeister&lt;/a&gt; is the story off the online mind mapping tool &#8220;The google docs of mind mapping&#8221; apparently.&lt;/p&gt;


	&lt;p&gt;&lt;a href=&quot;http://www.mindmeister.com/&quot;&gt;MindMeister&lt;/a&gt; It&#8217;s all &lt;span class=&quot;caps&quot;&gt;AJAX&lt;/span&gt; (and a lot of it), tough call I think the interface could be way better in Flex and you have offline Mind-mapping possibilities with &lt;span class=&quot;caps&quot;&gt;AIR&lt;/span&gt;.&lt;/p&gt;


	&lt;p&gt;They started with prototyping, then some design concepts , which all looked quite good if you ask me.&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;The name was the hardest thing to fine.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;I hear that.. It is very hard to find a name. I agree you shouldn&#8217;t be obsessed with finding a free .com domain name, 37signals never did.&lt;/p&gt;


	&lt;p&gt;Private betas are good, 2 launches making it exclusive with lots of feedback. Starting with just friends but allowing invites to others. No longer than 2 months with an upgrade offer at the end.&lt;/p&gt;


	&lt;p&gt;They got lots of competitors and clones after launching which I think is a common problem, just make sure you are the brightest and the best. MindMeister have some good user stats, better traffic than their competitors (according to Alexa) but less features than the competitors. Usability is what makes them better. Every euro spent on design is worth it..&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Recommendations&lt;/strong&gt;&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Get a great designer on board&lt;/li&gt;
		&lt;li&gt;Target non-technical users&lt;/li&gt;
		&lt;li&gt;Watch every Apple demo&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;&lt;strong&gt;Marketing&lt;/strong&gt;&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Write to bloggers&lt;/li&gt;
		&lt;li&gt;Post site to app portals&lt;/li&gt;
		&lt;li&gt;Create an &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt;&lt;/li&gt;
		&lt;li&gt;Write regular newsletter &#38; blog posts&lt;/li&gt;
		&lt;li&gt;&#8220;Add to del.icio.us / digg&#8221; button&lt;/li&gt;
		&lt;li&gt;Spend time (and money) on &lt;span class=&quot;caps&quot;&gt;SEO&lt;/span&gt;&lt;/li&gt;
		&lt;li&gt;Be generous with Premium accounts&lt;/li&gt;
		&lt;li&gt;Don&#8217;t comment spam&lt;/li&gt;
		&lt;li&gt;Don&#8217;t pay for placements and ads&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;Don&#8217;t start charging before its really stable&lt;/li&gt;
		&lt;li&gt;Carefully select premium features&lt;/li&gt;
		&lt;li&gt;Think of students et al&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;&lt;strong&gt;Technical Issues&lt;/strong&gt;&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Everybody has them&lt;/li&gt;
		&lt;li&gt;It pays to be honest&lt;/li&gt;
		&lt;li&gt;Explain what happened&lt;/li&gt;
		&lt;li&gt;Announce maintenance windows&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;It seems MindMeister are going offline with Google Gears which is the right move, maybe &lt;span class=&quot;caps&quot;&gt;AJAX&lt;/span&gt; was a good choice after all. Use a canvas library which turns to &lt;span class=&quot;caps&quot;&gt;VRML&lt;/span&gt; on IE.. And &lt;a href=&quot;https://www.wirecard.com/wirecard/&quot;&gt;Wirecard&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;I&#8217;ve got to day playing with it now &lt;a href=&quot;http://www.mindmeister.com/&quot;&gt;MindMeister&lt;/a&gt; is pretty good, its slick works well and I can see how it would be both useful and easy with is important in brainstorming tools. Bravo guys!&lt;/p&gt;


	&lt;p&gt;&lt;a href=&quot;http://www.liverail.net/assets/2007/9/19/19092007056.jpg&quot;&gt;&lt;img src=&quot;http://www.liverail.net/assets/2007/9/19/19092007056_thumb.jpg&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://www.liverail.net/assets/2007/9/19/19092007057.jpg&quot;&gt;&lt;img src=&quot;http://www.liverail.net/assets/2007/9/19/19092007057_thumb.jpg&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://www.liverail.net/assets/2007/9/19/19092007059.jpg&quot;&gt;&lt;img src=&quot;http://www.liverail.net/assets/2007/9/19/19092007059_thumb.jpg&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://www.liverail.net/assets/2007/9/19/19092007060.jpg&quot;&gt;&lt;img src=&quot;http://www.liverail.net/assets/2007/9/19/19092007060_thumb.jpg&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


	&lt;h3&gt;Outsourcing to Open Source&lt;/h3&gt;


	&lt;p&gt;Another non-technical session &lt;a href=&quot;http://conferences.oreillynet.com/cs/railseurope2007/view/e_sess/13374&quot;&gt;Outsourcing to Open Source&lt;/a&gt; from Tobias Luetke at &#8220;Shopify&#8217;:http://www.shopify.com/. I chose this because i&#8217;m a real fan of Shopify, JapedPixel and because it&#8217;s more relevant to my business than the others. But I wish I could also have gone to &lt;a href=&quot;http://conferences.oreillynet.com/cs/railseurope2007/view/e_sess/14076&quot;&gt;Exploring Very Rapid Web Development Techniques with Hobo&lt;/a&gt; by Tom Locke, but those the breaks..&lt;/p&gt;


	&lt;p&gt;&lt;a href=&quot;http://www.liverail.net/assets/2007/9/19/Picture_1.png&quot;&gt;&lt;img src=&quot;http://www.liverail.net/assets/2007/9/19/Picture_1_thumb.png&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;Tobias is talking about &lt;a href=&quot;http://www.liquidmarkup.org/&quot;&gt;Liquid&lt;/a&gt; which for those that don&#8217;t know is a &lt;strong&gt;safe&lt;/strong&gt; templating method for Rails which you can give to customers to make their own designs/themes without them breaking your app. And he wrote it on the plain to RailsConf 2005!! Not only is it safe but only exposes what you want to expose ie.&lt;/p&gt;


&lt;pre&gt;
&lt;code class=&quot;ruby&quot;&gt;
class Product &amp;lt;&amp;lt; ActiveRecord::Base
liquid_methods :title, :price, :description
&lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;&lt;a href=&quot;http://www.liverail.net/assets/2007/9/19/19092007061.jpg&quot;&gt;&lt;img src=&quot;http://www.liverail.net/assets/2007/9/19/19092007061_thumb.jpg&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;If you don&#8217;t know about liquid, go look it up. If you ever developing a SaaS with needs safe themes for users, its a great fit. Tobias is also talking about Vision which is a downloadable theme engine which works offline. Using this tool the launched a competition for themes for shopify with an iPod nano, the people who entered then now do full time Shopify themeing and earn more money from it than JadedPixel!!&lt;/p&gt;


	&lt;p&gt;Vision works by donwloading a Mock version of Shopify with no backend but the objects returned have real like data. Like a massive test case your users can download and theme.&lt;/p&gt;


	&lt;p&gt;&lt;a href=&quot;http://www.liverail.net/assets/2007/9/19/19092007062.jpg&quot;&gt;&lt;img src=&quot;http://www.liverail.net/assets/2007/9/19/19092007062_thumb.jpg&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://www.liverail.net/assets/2007/9/19/19092007063.jpg&quot;&gt;&lt;img src=&quot;http://www.liverail.net/assets/2007/9/19/19092007063_thumb.jpg&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;JapedPixel also issued the open source &lt;a href=&quot;http://www.activemerchant.org/&quot;&gt;AcitveMerchant&lt;/a&gt; as a library for payment processing gateways. It is really useful contribution to Rails. It supports 40+ gateways. Often they are commission by shopify customers who pay a ruby developer to contribute a specific merchant to ActiveMerchant which then automatically appears in Shopify. This is a great example of crowd-sourcing helping the community which then helps your product. It&#8217;s like work for free&#8230;.&lt;/p&gt;


	&lt;p&gt;&lt;a href=&quot;http://www.liverail.net/assets/2007/9/19/19092007064.jpg&quot;&gt;&lt;img src=&quot;http://www.liverail.net/assets/2007/9/19/19092007064_thumb.jpg&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Crowdsourcing&lt;/strong&gt;&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;Crowdsourcing is a neologism for the act of taking a job traditionally performed by an employee or contractor, and outsourcing it to an undefined, generally large group of people, in the form of an open call. For example, the public may be invited to develop a new technology, carry out a design task, refine an algorithm or help analyze large amounts of data.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;Examples of crowdsourcing are threadless.com, freebase, Mechanical Turk, PeertoPatent, OrganizedWisdom. Tobias simple example of CrowdSourcing is giving your users the ability to create a new translation of text in checkout and feed that back to the system. They get credit for the translation and shopify track the progress of translation. This allows them to email authors when they add a new string that needs translation.&lt;/p&gt;


	&lt;p&gt;&lt;a href=&quot;http://www.liverail.net/assets/2007/9/19/19092007065.jpg&quot;&gt;&lt;img src=&quot;http://www.liverail.net/assets/2007/9/19/19092007065_thumb.jpg&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;A really good talk from Tobias but he could have gone into the theme of crowd-sourcing more than than shopifies use of it, then given the examples. Just a structural thing.&lt;/p&gt;


	&lt;p&gt;For those interested. Shopify use &lt;a href=&quot;http://lucene.apache.org/solr/&quot;&gt;Solr&lt;/a&gt; and love it. From being a public facing Rails application they get some really random requests such as a whole Shakespeare text in a param!. The run 25,000 public facing with different URLs, so they get a lot of web-spiders on the servers. They use memcache generating a unique key for every possible input for a page, check memcache to see if it has a version. If memcache doesn&#8217;t have it they gzip it and stick it in memcache. They use version numbers of each object and the version number is part of the key, instead of expiring they just have to lookup a new key and get a cachemiss so generate it. No cache invalidation.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.liverail.net/">
    <author>
      <name>stuarteccles</name>
    </author>
    <id>tag:www.liverail.net,2007-09-19:2608</id>
    <published>2007-09-19T09:38:00Z</published>
    <updated>2008-02-14T18:00:38Z</updated>
    <category term="RubyOnRails"/>
    <category term="amf. weborb"/>
    <category term="flex"/>
    <category term="rails"/>
    <category term="Rails"/>
    <category term="RailsConfEurope"/>
    <category term="railsconfeurope"/>
    <category term="slingshot"/>
    <category term="thermo"/>
    <link href="http://www.liverail.net/articles/2007/9/19/railsconf-europe-wednesday-sessions" rel="alternate" type="text/html"/>
    <title>RailsConf Europe - Wednesday Sessions - 1</title>
<content type="html">
            &lt;p&gt;Trying to make better choices today which shouldn&#8217;t be too hard. So I decided on following up my Flex on Rails background (which I havn&#8217;t be exploring recently), but since I was the first tutorial on integrating Flex and Rails, I thought i&#8217;d check on it&#8217;s progress.&lt;/p&gt;


	&lt;h3&gt;Building Rich Internet Applications with Flex and Ruby on Rails&lt;/h3&gt;


	&lt;p&gt;This &lt;a href=&quot;http://www.railsconfeurope.com/cs/railseurope2007/view/e_sess/14234&quot;&gt;session&lt;/a&gt; was given by Simeon Bateman, who although not Adobe is certainly a Flex expert and has real world in-anger experience of Flex and Rails.&lt;/p&gt;


	&lt;p&gt;Unfortunately Simeon spent far too much time on Flash background and had some problems with the Internet before getting to the good stuff. But did manage to quick demonstrations of&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;HTTPService using &lt;span class=&quot;caps&quot;&gt;XML REST&lt;/span&gt; responses from Rails&lt;/li&gt;
		&lt;li&gt;&lt;span class=&quot;caps&quot;&gt;AMF&lt;/span&gt; using &lt;a href=&quot;http://www.themidnightcoders.com/weborb/rubyonrails/index.htm&quot;&gt;WebORB&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;span class=&quot;caps&quot;&gt;AMF&lt;/span&gt; using &lt;a href=&quot;http://rubyamf.org/&quot;&gt;RubyAMF&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;To his credit the last 15 mins was some of the best and explained the advantages of &lt;span class=&quot;caps&quot;&gt;AMF&lt;/span&gt; over HTTPService with great examples. Simeon reckons that RubyAMF is the way to go in the future as WebORB has not been updated in a year, other people I know concur with that.&lt;/p&gt;


	&lt;p&gt;The other question for people interested in Flash/Flex is:&lt;/p&gt;


	&lt;p&gt;&lt;a href=&quot;http://blog.digitalbackcountry.com/?p=1043&quot;&gt;What is Thermo?&lt;/a&gt;&lt;/p&gt;


	&lt;h3&gt;Creating Hybrid Web and Desktop Applications with Rails and Slingshot&lt;/h3&gt;


	&lt;p&gt;A &lt;a href=&quot;http://www.railsconfeurope.com/cs/railseurope2007/view/e_sess/14269&quot;&gt;session&lt;/a&gt; by &lt;a href=&quot;http://joyent.com/&quot;&gt;Joyent&lt;/a&gt; on &lt;a href=&quot;http://joyent.com/developers/slingshot/&quot;&gt;Slingshot&lt;/a&gt;. This is something i&#8217;ve had an interest in for a while, in the realms of the online/offline applications. In theory Slingshot offers downloadable Rails applications that run on the desktop but syncs with an online web-application.&lt;/p&gt;


	&lt;p&gt;It will do syncronisations, and you can extend the sync-hooks and will need to implement &lt;strong&gt;aggregate_data&lt;/strong&gt; for your models to get the sync works. But it won&#8217;t do conflict resolutions, but it does handle auto-increment ids and foreign-key problems on the syncronisation side which is a pretty tough problem. It can also sync files as well as data between online and offline. You must have timestamps on your model to sync models which make sense.&lt;/p&gt;


	&lt;p&gt;I will do some drag and drop stuff but only on Mac &lt;span class=&quot;caps&quot;&gt;OS X&lt;/span&gt;. This is a real problem, and certainly &lt;span class=&quot;caps&quot;&gt;AIR&lt;/span&gt; could overtake easily in this area. I would like to see how I could get RailsDAV working with Slingshot on this.&lt;/p&gt;


	&lt;p&gt;Your code will be visible in the download, it is after all Ruby. So it better be open-source application on a behind firewall deployment. I don&#8217;t think this is this biggest problem as people won&#8217;t be able to copy it without the web-application component.&lt;/p&gt;


	&lt;p&gt;They downloads can be big. 20MB is the initial hit and applications can be as big as 100MB.&lt;/p&gt;


	&lt;p&gt;Overall it seems better on Mac &lt;span class=&quot;caps&quot;&gt;OSX&lt;/span&gt; than Windows. It has &lt;span class=&quot;caps&quot;&gt;DMG&lt;/span&gt; packaging, XCode customisation and changing Info.plist while the Windows deployment looks a lot harder.&lt;/p&gt;


	&lt;p&gt;&lt;a href=&quot;http://www.liverail.net/assets/2007/9/19/19092007050.jpg&quot;&gt;&lt;img src=&quot;http://www.liverail.net/assets/2007/9/19/19092007050_thumb.jpg&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://www.liverail.net/assets/2007/9/19/19092007048.jpg&quot;&gt;&lt;img src=&quot;http://www.liverail.net/assets/2007/9/19/19092007048_thumb.jpg&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;In practice, its not complete. Here is a list of things it won&#8217;t do (Yet)&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;sync conflict resolution&lt;/li&gt;
		&lt;li&gt;encrypt your code&lt;/li&gt;
		&lt;li&gt;domain specific online/offline issues&lt;/li&gt;
		&lt;li&gt;package you application automatically&lt;/li&gt;
		&lt;li&gt;update itself + your Rails app code &lt;/li&gt;
		&lt;li&gt;native menus&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;But this is still one of the most interesting and innovative things being talked about at RailsConf Europe so was certainly worth intending. The presentation was well done and paced well, including presentation then questions then demo which is a lot to fill 45 minutes. Showing you don&#8217;t have to aim your presentation at the lowest common demoninator.&lt;/p&gt;


	&lt;p&gt;I&#8217;m wondering if you could just use the sync_controller parts of slingshot and write an &lt;span class=&quot;caps&quot;&gt;AIR&lt;/span&gt; end&#8230;. Evil but useful.&lt;/p&gt;


	&lt;p&gt;Great demo..&lt;/p&gt;


	&lt;p&gt;&lt;a href=&quot;http://www.liverail.net/assets/2007/9/19/19092007051.jpg&quot;&gt;&lt;img src=&quot;http://www.liverail.net/assets/2007/9/19/19092007051_thumb.jpg&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://www.liverail.net/assets/2007/9/19/19092007052.jpg&quot;&gt;&lt;img src=&quot;http://www.liverail.net/assets/2007/9/19/19092007052_thumb.jpg&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://www.liverail.net/assets/2007/9/19/19092007053.jpg&quot;&gt;&lt;img src=&quot;http://www.liverail.net/assets/2007/9/19/19092007053_thumb.jpg&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://www.liverail.net/assets/2007/9/19/19092007054.jpg&quot;&gt;&lt;img src=&quot;http://www.liverail.net/assets/2007/9/19/19092007054_thumb.jpg&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.liverail.net/">
    <author>
      <name>stuarteccles</name>
    </author>
    <id>tag:www.liverail.net,2007-09-19:2607</id>
    <published>2007-09-19T07:49:00Z</published>
    <updated>2007-09-19T08:14:33Z</updated>
    <category term="RubyOnRails"/>
    <category term="RailsConfEurope"/>
    <link href="http://www.liverail.net/articles/2007/9/19/railsconf-europe" rel="alternate" type="text/html"/>
    <title>RailsConf Europe - Wednesday Keynotes</title>
<content type="html">
            &lt;p&gt;Partly due to having to check out my hotel, partly due to my hangover and partly due to not being bothered I missed today&#8217;s pre-roller advert by ThoughtWorks to today&#8217;s keynotes.&lt;/p&gt;


	&lt;p&gt;But i&#8217;m here now for the session on &lt;a href=&quot;http://www.railsconfeurope.com/cs/railseurope2007/view/e_sess/14721&quot;&gt;Best Practices&lt;/a&gt;. A bit late. Siting at the back nursing my headache.&lt;/p&gt;


	&lt;p&gt;The Best Practices session is very codey but still entertaining so far covering test-first, associations, method naming and chaining. Expressive Interfaces they call them, readability and undestanding. Now moving on to &lt;strong&gt;with_scope&lt;/strong&gt; and the dangers of using a &lt;strong&gt;before_filter&lt;/strong&gt; with a scoped command, hence reducing all queries to a limited scope. For instance only finding posts for the current user. Instead use associations:&lt;/p&gt;


&lt;pre&gt;
&lt;code class=&quot;ruby&quot;&gt;
current_user.posts.find(params[id])
&lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;But it has uses. You can use method_messaging with a with_scope and create a dynamic &lt;strong&gt;has_many&lt;/strong&gt; association through a proxy. Similarly very cool but I can see that being mis-used also. I think using method_missing should be a last resort, documented heavily and only used if it significantly improves readability or time. Not really as a best practice.&lt;/p&gt;


	&lt;p&gt;The use of conditions and commands in Ruby can be confusing as there is many ways of doing it. The question, which can be understood quickest?&lt;/p&gt;


&lt;pre&gt;
&lt;code class=&quot;ruby&quot;&gt;
command if conditional?
....
if conditional?
  command
end
...
conditional? and command
...
conditional? &#38;&#38; command
...
&lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;All of the above do the same. For me number 2 is clearest but involves more typing, but I hate mixing up commands with conditionals in an expression, and the speakers agree.&lt;/p&gt;


	&lt;p&gt;&lt;a href=&quot;http://www.liverail.net/assets/2007/9/19/19092007047.jpg&quot;&gt;&lt;img src=&quot;http://www.liverail.net/assets/2007/9/19/19092007047_thumb.jpg&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.liverail.net/">
    <author>
      <name>stuarteccles</name>
    </author>
    <id>tag:www.liverail.net,2007-09-18:2604</id>
    <published>2007-09-18T15:28:00Z</published>
    <updated>2008-02-14T18:01:23Z</updated>
    <category term="RailsConfEurope"/>
    <category term="railsconfeurope"/>
    <link href="http://www.liverail.net/articles/2007/9/18/railsconf-europe-tuesday-keynotes" rel="alternate" type="text/html"/>
    <title>RailsConf Europe - Tuesday Keynotes</title>
<content type="html">
            &lt;p&gt;Tuesday is ending now with some final keynotes&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;http://www.railsconfeurope.com/cs/railseurope2007/view/e_sess/14851&quot;&gt;Beyond Startups: Rails Demand in the Global 2000&lt;/a&gt; Jonathan Siegel, President, &lt;span class=&quot;caps&quot;&gt;ELC&lt;/span&gt; Technology&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;http://www.railsconfeurope.com/cs/railseurope2007/view/e_sess/14847&quot;&gt;The Rest of &lt;span class=&quot;caps&quot;&gt;REST&lt;/span&gt;&lt;/a&gt; Roy T. Fielding, Chief Scientist, Day Software &lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;http://www.railsconfeurope.com/cs/railseurope2007/view/e_sess/14939&quot;&gt;Rails and the Next Generation Web&lt;/a&gt; Craig R. McClanahan, Senior Software Engineer, Sun Microsystems, Inc.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Basically sandwiching in Roy Fielding, a uber-guru of the web between some Diamond sponsors seems like a commercialization thing. A theme of the conference maybe.&lt;/p&gt;


	&lt;h3&gt;Beyond Startups: Rails Demand in the Global 2000&lt;/h3&gt;


	&lt;p&gt;Thanks to Jonathan Siegel we heard the obvious, that yes some Global 2000 companies are starting to use Rails. Big shock. Shame the man can&#8217;t present at all. Little note, if your sponsorship money buys you a presentation, learn how to present an engaging talk.&lt;/p&gt;


	&lt;h3&gt;The Rest of &lt;span class=&quot;caps&quot;&gt;REST&lt;/span&gt;&lt;/h3&gt;


	&lt;p&gt;An intellectual and precise talk by Roy Fielding, was interesting and historically educating but academic for most people there. Still I find the elements of architectural style and forming lasting styles of architecture is really interesting from a consulting point of view. The architectural style a way of deducing principles of technology removed from any of the problems of actual languages and products.&lt;/p&gt;


	&lt;p&gt;&lt;a href=&quot;http://www.liverail.net/assets/2007/9/18/18092007040.jpg&quot;&gt;&lt;img src=&quot;http://www.liverail.net/assets/2007/9/18/18092007040_thumb.jpg&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://www.liverail.net/assets/2007/9/18/18092007041.jpg&quot;&gt;&lt;img src=&quot;http://www.liverail.net/assets/2007/9/18/18092007041_thumb.jpg&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


	&lt;h3&gt;Rails and the Next Generation Web&lt;/h3&gt;


	&lt;p&gt;Craig McClanahan is a great speaker and someone we are interested to hear from. This should be the principle of buying your speaking slot, put up something interesting with an interesting topic, not just a marketing speech.&lt;/p&gt;


	&lt;p&gt;Craig talks about his love of Ruby and Rails even after being a Java-guy for so many years. A shift for Sun? Rich Internet Applications and Horizontal scaling, gone is Moore&#8217;s Law. Well Craig says that Java web frameworks pace of innovation is slowing, and the Java community know they need to look to the future. Could the Rails community go snow-blind also? Forget to look to the future..&lt;/p&gt;


	&lt;p&gt;Mentions three plugins. act_as_cached, act_as_state_machine, will_paginate&#8230; get it wrong as they only extend ActiveRecord. While acts_as_autenticator, paginator gets it right as they don&#8217;t care about the implementation.&lt;/p&gt;


	&lt;p&gt;make_resourceful plugin is a good example of separating &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; from implementation where you could plugin ActiveResource or ActiveRecord.&lt;/p&gt;


	&lt;p&gt;Unfortunately Craig only has 50 minutes which is no time at all. I would love to hear a proper 2 hr talk from him as it seems he has some great stuff to say.&lt;/p&gt;


	&lt;p&gt;&lt;a href=&quot;http://www.liverail.net/assets/2007/9/18/18092007042.jpg&quot;&gt;&lt;img src=&quot;http://www.liverail.net/assets/2007/9/18/18092007042_thumb.jpg&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://www.liverail.net/assets/2007/9/18/18092007043.jpg&quot;&gt;&lt;img src=&quot;http://www.liverail.net/assets/2007/9/18/18092007043_thumb.jpg&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://www.liverail.net/assets/2007/9/18/18092007044.jpg&quot;&gt;&lt;img src=&quot;http://www.liverail.net/assets/2007/9/18/18092007044_thumb.jpg&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.liverail.net/">
    <author>
      <name>stuarteccles</name>
    </author>
    <id>tag:www.liverail.net,2007-09-18:2603</id>
    <published>2007-09-18T14:57:00Z</published>
    <updated>2008-02-14T18:02:19Z</updated>
    <category term="RubyOnRails"/>
    <category term="RailsConfEurope"/>
    <category term="railsconfeurope"/>
    <link href="http://www.liverail.net/articles/2007/9/18/railsconf-europe-choosing-sessions-is-so-hard" rel="alternate" type="text/html"/>
    <title>RailsConf Europe - Choosing sessions is so hard...</title>
<content type="html">
            &lt;p&gt;Tuesday at RailsConf and choosing sessions is damn hard. Am I missing out on something really great going on in other room? Could the other guys be as boring as this speaker? With nothing more than a title and a synopsis we select from our buffet.&lt;/p&gt;


	&lt;p&gt;My bad decisions so far:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Chose &lt;a href=&quot;http://www.railsconfeurope.com/cs/railseurope2007/view/e_sess/14415&quot;&gt;Making Rails More (Artificially) Intelligent&lt;/a&gt;. Should have chosen &lt;a href=&quot;http://www.railsconfeurope.com/cs/railseurope2007/view/e_sess/14271&quot;&gt;Deployment and Continuous Integration from the Trenches&lt;/a&gt;. Although non of the first sessions were apparently great&lt;/li&gt;
		&lt;li&gt;Chose &lt;a href=&quot;http://www.railsconfeurope.com/cs/railseurope2007/view/e_sess/14243&quot;&gt;Meta-Magic in Rails: Become a Master Magician&lt;/a&gt;. Should have chosen &lt;a href=&quot;http://www.railsconfeurope.com/cs/railseurope2007/view/e_sess/14243&quot;&gt;Meta-Magic in Rails: Become a Master Magician&lt;/a&gt;. Very funny, entertaining, informative and very very popular.&lt;/li&gt;
		&lt;li&gt;Chose &lt;a href=&quot;http://www.railsconfeurope.com/cs/railseurope2007/view/e_sess/14196&quot;&gt;Really Scaling Rails&lt;/a&gt;. Should have chosen &lt;a href=&quot;http://www.railsconfeurope.com/cs/railseurope2007/view/e_sess/14213&quot;&gt;Utilizing Amazon S3 and &lt;span class=&quot;caps&quot;&gt;EC2&lt;/span&gt; in Rails&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;Chose &lt;a href=&quot;http://www.railsconfeurope.com/cs/railseurope2007/view/e_sess/14204&quot;&gt;Tabnav: Do We Really Need a Plugin for Tabbed Navigation?&lt;/a&gt;. Should have chosen &lt;a href=&quot;http://www.railsconfeurope.com/cs/railseurope2007/view/e_sess/14204&quot;&gt;Tabnav: Do We Really Need a Plugin for Tabbed Navigation?&lt;/a&gt;. Although I hear &lt;a href=&quot;http://www.railsconfeurope.com/cs/railseurope2007/view/e_sess/15113&quot;&gt;Rubinius, Improving The Rails Ecosystem&lt;/a&gt; was really good, the Tabnav talk was entertaining and something I may use soon.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;h3&gt;Making Rails More (Artificially) Intelligent&lt;/h3&gt;


	&lt;p&gt;The speakers were in Spanish and their English was difficult to understand especially in a presentation context, but well done for giving it a go guys. Basically the talk introduced Bayesian graphs and probability tables, Bayesian classifiers and genetic algorithms and some Ruby libraries for using them. Unfortunately they didn&#8217;t make the Rails context at all. I think a talk on using these kind of algorithmic tools would be a winner with the right presentation context. But hard when it&#8217;s not your first language.&lt;/p&gt;


	&lt;p&gt;I learnt something and it&#8217;s worth checking the libraries if you ever feel you&#8217;ll need to solve an AI problem.&lt;/p&gt;


	&lt;h3&gt;Meta-Magic in Rails: Become a Master Magician&lt;/h3&gt;


	&lt;p&gt;Very entertaining and very popular, if the conference room had rafters people would be hanging from them. The room was packed. I would hate to go up against Dr Nic, the other rooms must have been empty.&lt;/p&gt;


	&lt;p&gt;&lt;a href=&quot;http://www.liverail.net/assets/2007/9/18/18092007035.jpg&quot;&gt;&lt;img src=&quot;http://www.liverail.net/assets/2007/9/18/18092007035_thumb.jpg&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;I quit coding because I thought I hated it, turned out I just hated Java.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;Dr Nic not only talked about fun little things with method_missing, const_missing and using the meta abilities of Ruby he used them as a weapon against other languages&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;Java is like&#8230; Keith Richards. not so cute anymore, can tell you stories about himself, can&#8217;t change his behavior&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;Great talk but Dr Nic was keen to point out that that in some cases the meta-magic is.&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;not useful but it is funny..&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;&lt;a href=&quot;http://www.liverail.net/assets/2007/9/18/18092007036.jpg&quot;&gt;&lt;img src=&quot;http://www.liverail.net/assets/2007/9/18/18092007036_thumb.jpg&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


	&lt;h3&gt;Really Scaling Rails&lt;/h3&gt;


	&lt;p&gt;Was by a Twitter guy on scaling and had some bits of useful information but really didn&#8217;t engage. The really useful elements were a few tips such as how to encode the page peformance into every the response of every page. A shame.&lt;/p&gt;


	&lt;p&gt;&lt;a href=&quot;http://www.liverail.net/assets/2007/9/18/18092007039.jpg&quot;&gt;&lt;img src=&quot;http://www.liverail.net/assets/2007/9/18/18092007039_thumb.jpg&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


	&lt;h3&gt;Tabnav: Do We Really Need a Plugin for Tabbed Navigation?&lt;/h3&gt;


	&lt;p&gt;A lovely talk by Italian speaker &lt;a href=&quot;http://www.railsconfeurope.com/cs/railseurope2007/view/e_spkr/3857&quot;&gt;Paolo Dona&lt;/a&gt; who was engaging and funny. I expected the room to be near empty, after all who needs to hear about tabbed navigation. Instead Paolo packed the small room he was given, obviously they knew more than me.&lt;/p&gt;


	&lt;p&gt;Paolo&#8217;s main thing was that sure Ruby on Rails has meant he has had to write less code but he still spends the same amount of time writing &lt;span class=&quot;caps&quot;&gt;HTML&lt;/span&gt;/CSS. In fact relatively he was spending much more time on &lt;span class=&quot;caps&quot;&gt;HTML&lt;/span&gt;/CSS than coding.&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;where is &lt;span class=&quot;caps&quot;&gt;DHH&lt;/span&gt;? I want to kill him. He has turned me into a designer.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;So Paolo has widgets&lt;/p&gt;


&lt;pre&gt;
  &lt;code class=&quot;console&quot;&gt;
ruby script/plugin install svn://svn.seesaw.it/widgets/trunk
&lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;Widgets for tabs, navigation, showhide, tablizer, tooltips, nubbins. To create user interface design patterns with less effort. It&#8217;s a fine idea and i&#8217;ll look to use them soon.&lt;/p&gt;


	&lt;p&gt;Not a bad spread for the food either&#8230;..&lt;/p&gt;


	&lt;p&gt;&lt;a href=&quot;http://www.liverail.net/assets/2007/9/18/18092007038.jpg&quot;&gt;&lt;img src=&quot;http://www.liverail.net/assets/2007/9/18/18092007038_thumb.jpg&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.liverail.net/">
    <author>
      <name>stuarteccles</name>
    </author>
    <id>tag:www.liverail.net,2007-09-18:2601</id>
    <published>2007-09-18T10:10:00Z</published>
    <updated>2007-09-19T12:37:57Z</updated>
    <category term="dave thomas"/>
    <category term="keynote"/>
    <category term="RailsConfEurope"/>
    <link href="http://www.liverail.net/articles/2007/9/18/railsconf-europe-dave-thomas-keynote" rel="alternate" type="text/html"/>
    <title>RailsConf Europe - Dave Thomas Keynote</title>
<content type="html">
            &lt;p&gt;Last night &lt;a href=&quot;http://pragdave.pragprog.com/&quot;&gt;Dave Thomas&lt;/a&gt; kicked off RailsConf Europe with something different. Rather than evangelize Rails or talk up the lastest/next big thing, Dave set the tone for the conference by stripping back it  to the core philosophy&#8217;s of software development and created a grand analogy.&lt;/p&gt;


	&lt;h2&gt;Rails and Art&lt;/h2&gt;


	&lt;p&gt;Dave&#8217;s well spoken, in a mid-atlantic accent, and funny keynote concentrated on the definition of software development as art or engineering. By making multiple analogies to software development to famous works of art and the methods of artists of history, Dave was trying to create a philosophy behind not just good software but truely great, beautiful software. He looked at four main things.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Starting&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;Just as the artist is faced with a blank canvas, the developer is faced with a blank &lt;span class=&quot;caps&quot;&gt;IDE&lt;/span&gt;. But an artist doesn&#8217;t jump right in and start to create the masterpiece. Instead the use sketching and work in other mediums to deduce how a masterpiece will evolve. Consequently the developer should work in other mediums, or index cards or lego. They could use prototyping of small complex areas, exploratory testing to validate understanding and creating a &#8220;tracer bullet&#8221;, a complete end-to-end system but without any details, later they can fill in the details or just start over.&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;be prepared to throw 10 away, because the 11th will be sweet.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;&lt;strong&gt;Stopping&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;In a grand mosiac such as the sistine chapel, its hard to be close to the detail when the work is so large. So Dave talks about about how to chapel is broken into panels, all unique &#8220;loosely coupled&#8221; but come together to tell a long story. Hence developers can set boundaries not just in function (modularisation) but in time then honouring those boundaries. Short distinct length development times and if your feature is only half finished at the end. Stop and be prepared to throw it out and do it again in the next iteration.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Satisfy the customer&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;Pictures versus portraits. An artist painting a portrait tries to look inside someone and find a way to express it, even if its abstract its still a representation. The developer needs to find a way to satisfy the underlying requirement.&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;Be in the habit  of not listening to the client.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;But to do so a developer needs to look beyond the surface, be appropriate, work with client and get to know them. Dave used two great anecdotes, the &lt;span class=&quot;caps&quot;&gt;NASA&lt;/span&gt; space pen (the real story) and the driving license camera as two conflicting stories. Where some clients don&#8217;t realize they have the need for a technology solution but some clients don&#8217;t need high technology, listen to what they really need.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Why&lt;/strong&gt;&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;There is art in engineering and engineering in art.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;blockquote&gt;
		&lt;p&gt;Be an artist. Create something great. Create something beautiful.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;blockquote&gt;
		&lt;p&gt;Sign your work. No more anonymous applications&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;&lt;strong&gt;My review&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;I really liked Dave Thomas&#8217;s keynote, he is a fine speaker, smart and inspirational. Talking to a few people afterwards there was a little &#8220;Yeah but that&#8217;s what we are like&#8230;&#8221; but for two things..&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;Not all developers are the artists they think they are.&lt;/li&gt;
		&lt;li&gt;The majority of development teams don&#8217;t know this at all, they are stuck in the production mentatility of &#8216;lines of code produced per hour&#8217; and &#8216;man-days effort&#8217;&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;I think Dave&#8217;s keynote would have gone down best with the non-technicals, the managers, the &lt;span class=&quot;caps&quot;&gt;CTO&lt;/span&gt;&#8217;s, the executives. Maybe then they can treat the developers a bit better than code generation machines and like real artisans.&lt;/p&gt;


	&lt;p&gt;&lt;a href=&quot;http://www.liverail.net/assets/2007/9/18/17092007033.jpg&quot;&gt;&lt;img src=&quot;http://www.liverail.net/assets/2007/9/18/17092007033_thumb.jpg&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://www.liverail.net/assets/2007/9/18/17092007031_1.jpg&quot;&gt;&lt;img src=&quot;http://www.liverail.net/assets/2007/9/18/17092007031_1_thumb.jpg&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;Stuart Eccles&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.liverail.net/">
    <author>
      <name>stuarteccles</name>
    </author>
    <id>tag:www.liverail.net,2007-09-18:2600</id>
    <published>2007-09-18T08:46:00Z</published>
    <updated>2007-09-19T12:38:14Z</updated>
    <category term="Liverail"/>
    <category term="RubyOnRails"/>
    <category term="berlin"/>
    <category term="RailsConfEurope"/>
    <link href="http://www.liverail.net/articles/2007/9/18/railsconf-europe-in-berlin" rel="alternate" type="text/html"/>
    <title>RailsConf Europe - In Berlin</title>
<content type="html">
            &lt;p&gt;I arrived in Berlin yesterday and the sun was shining, that makes a change from London but today its raining, so exactly like London.&lt;/p&gt;


	&lt;p&gt;There is a large assembly of Railers, official figures have 39% Germans, 19% Brits, 11% Americans and the rest. Dave Thomas did his keynote last night (more to come) and &lt;span class=&quot;caps&quot;&gt;DHH&lt;/span&gt; is just finishing his this morning.&lt;/p&gt;


	&lt;p&gt;I have some starter pictures for you:&lt;/p&gt;


	&lt;p&gt;&lt;a href=&quot;http://www.liverail.net/assets/2007/9/18/17092007034.jpg&quot;&gt;&lt;img src=&quot;http://www.liverail.net/assets/2007/9/18/17092007034_thumb.jpg&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://www.liverail.net/assets/2007/9/18/17092007028.jpg&quot;&gt;&lt;img src=&quot;http://www.liverail.net/assets/2007/9/18/17092007028_thumb.jpg&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://www.liverail.net/assets/2007/9/18/17092007030.jpg&quot;&gt;&lt;img src=&quot;http://www.liverail.net/assets/2007/9/18/17092007030_thumb.jpg&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.liverail.net/">
    <author>
      <name>stuarteccles</name>
    </author>
    <id>tag:www.liverail.net,2007-09-13:2559</id>
    <published>2007-09-13T08:38:00Z</published>
    <updated>2007-09-13T08:49:57Z</updated>
    <category term="RubyOnRails"/>
    <category term="railsconf"/>
    <link href="http://www.liverail.net/articles/2007/9/13/liverail-off-to-berlin-railsconf-europe" rel="alternate" type="text/html"/>
    <title>LiveRail off to Berlin RailsConf Europe</title>
<content type="html">
            &lt;p&gt;Just to confirm that I will be off to Berlin next week and will be hanging around at RailsConf Europe on the 18-19th. If you want to talk RailsDAV, Flex with Rails, Facebook or the state of the media industry in London, ask around for me.&lt;/p&gt;


	&lt;p&gt;I&#8217;ll be blogging from the event also, like many many others ;-)&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.liverail.net/">
    <author>
      <name>stuarteccles</name>
    </author>
    <id>tag:www.liverail.net,2007-07-27:2174</id>
    <published>2007-07-27T10:04:00Z</published>
    <updated>2008-02-14T18:03:05Z</updated>
    <category term="Facebook"/>
    <category term="RubyOnRails"/>
    <category term="facebook"/>
    <category term="plugin"/>
    <category term="rails"/>
    <category term="Rails"/>
    <category term="rfacebook"/>
    <category term="ruby"/>
    <link href="http://www.liverail.net/articles/2007/7/27/great-plugin-for-facebook-apps" rel="alternate" type="text/html"/>
    <title>Great Plugin for Facebook Apps</title>
<content type="html">
            &lt;p&gt;If you&#8217;ve been working through the Facebook/Rails tutorials you might find this plugin useful.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;http://code.google.com/p/facebook-rails/&quot;&gt;Facebook on Rails is a sexy plugin for developing Facebook apps&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;It adds some useful functions to Rails for creating a Facebook application.&lt;/p&gt;


	&lt;h3&gt;acts_as_fb_user&lt;/h3&gt;


&lt;pre&gt;
&lt;code class=&quot;ruby&quot;&gt;
class CreateUsers &amp;lt; ActiveRecord::Migration
  def self.up
    create_table :users do |t|
      t.column :uid, :integer, :null =&amp;gt; false
      t.column :session_key, :string
    end

    add_index :users, :uid, :unique
  end

  def self.down
    drop_table :users
  end
end

class User &amp;lt; ActiveRecord::Base
  acts_as_fb_user

  def self.import(fbsession)
    user = self.find_or_initialize_by_uid(fbsession.session_user_id)

    # Assumes session_key never expires
    if fbsession.session_key != user.session_key
      user.session_key = fbsession.session_key
      user.save!
    end

    return user
  end
end

&lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;you can now do things with the user object such as get a user&#8217;s friends&lt;/p&gt;


&lt;pre&gt;
&lt;code class=&quot;ruby&quot;&gt;
&amp;gt;&amp;gt; u = User.find(1)
=&amp;gt; #&amp;lt;User:...&amp;gt;
&amp;gt;&amp;gt; u.friends
=&amp;gt; [1, 2, 3]
&lt;/code&gt;
&lt;/pre&gt;

	&lt;h3&gt;FBMLController&lt;/h3&gt;


	&lt;p&gt;You can create FBMLControllers such as&lt;/p&gt;


&lt;pre&gt;
&lt;code class=&quot;ruby&quot;&gt;
class ApplicationController &amp;lt; Facebook::FBMLController
  before_filter :require_facebook_install
  before_filter :import_user

  private
  def import_user
    @user = User.import(fbsession)
  end
end
&lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;Although I still feel this doesnt need to be inherited and such just extend the ApplicationController.&lt;/p&gt;


	&lt;h3&gt;&lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; Calls.&lt;/h3&gt;


	&lt;p&gt;Are now easier, no need to parse the Hpricot &lt;span class=&quot;caps&quot;&gt;XML&lt;/span&gt;. And also you can use the fbsession in the Model objects (where it belongs)&lt;/p&gt;


&lt;pre&gt;
&lt;code class=&quot;ruby&quot;&gt;
class MyController &amp;lt; Facebook::FBMLController
  def friends
    @me         = Facebook::Users.get_info(fbsession.session_user_id, ['first_name', 'last_name'])
    @first_name = @me.first_name
    @last_name  = @me.last_name
    @friends    = Facebook::Friends.get
  end
end
&lt;/code&gt;
&lt;/pre&gt;

	&lt;h3&gt;Notifications like ActionMailer&lt;/h3&gt;


&lt;pre&gt;
&lt;code class=&quot;ruby&quot;&gt;
class StampNotificationPublisher &amp;lt; Facebook::NotificationPublisher
  def stamp(friends)
    @to_ids = friends.map(&#38;:uid)
    @text   = &quot;just stamped on you&quot; 
  end
end
&lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;I advise you check it out if you plan to write any applications for Facebook.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.liverail.net/">
    <author>
      <name>stuarteccles</name>
    </author>
    <id>tag:www.liverail.net,2007-07-16:2021</id>
    <published>2007-07-16T16:47:00Z</published>
    <updated>2007-07-27T10:03:54Z</updated>
    <category term="Facebook"/>
    <category term="RubyOnRails"/>
    <category term="facebook"/>
    <category term="ruby"/>
    <category term="rubyonrails"/>
    <category term="tutorial"/>
    <link href="http://www.liverail.net/articles/2007/7/16/continuing-facebook-applications-with-ruby-on-rails" rel="alternate" type="text/html"/>
    <title>Continuing Facebook Applications with Ruby On Rails</title>
<summary type="html">&lt;p&gt;This is the continuing tutorial from the last post &lt;a href=&quot;http://www.liverail.net/articles/2007/6/29/tutorial-on-developing-a-facebook-platform-application-with-ruby-on-rails&quot;&gt;Tutorial on developing a Facebook platform application with Ruby On Rails&lt;/a&gt; where we can take the social recipe application and add some more Facebook features including posting to the feed, profile boxes, profile actions, the Facebook Query Language and sending out invitations to a user&#8217;s friends to come join in the cooking fun (oh boy). So lets get down to it, I&#8217;m presuming you have been through the first tutorial and have a working Facebook application. Even if you havn&#8217;t got it deployed today&#8217;s examples will work with an &lt;span class=&quot;caps&quot;&gt;IFRAME&lt;/span&gt; application also.&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;This is the continuing tutorial from the last post &lt;a href=&quot;http://www.liverail.net/articles/2007/6/29/tutorial-on-developing-a-facebook-platform-application-with-ruby-on-rails&quot;&gt;Tutorial on developing a Facebook platform application with Ruby On Rails&lt;/a&gt; where we can take the social recipe application and add some more Facebook features including posting to the feed, profile boxes, profile actions, the Facebook Query Language and sending out invitations to a user&#8217;s friends to come join in the cooking fun (oh boy). So lets get down to it, I&#8217;m presuming you have been through the first tutorial and have a working Facebook application. Even if you havn&#8217;t got it deployed today&#8217;s examples will work with an &lt;span class=&quot;caps&quot;&gt;IFRAME&lt;/span&gt; application also.&lt;/p&gt;
&lt;p&gt;This is the continuing tutorial from the last post &lt;a href=&quot;http://www.liverail.net/articles/2007/6/29/tutorial-on-developing-a-facebook-platform-application-with-ruby-on-rails&quot;&gt;Tutorial on developing a Facebook platform application with Ruby On Rails&lt;/a&gt; where we can take the social recipe application and add some more Facebook features including posting to the feed, profile boxes, profile actions, the Facebook Query Language and sending out invitations to a user&#8217;s friends to come join in the cooking fun (oh boy). So lets get down to it, I&#8217;m presuming you have been through the first tutorial and have a working Facebook application. Even if you havn&#8217;t got it deployed today&#8217;s examples will work with an &lt;span class=&quot;caps&quot;&gt;IFRAME&lt;/span&gt; application also.&lt;/p&gt;


	&lt;p&gt;Before we get into it &lt;a href=&quot;http://blog.evanweaver.com/&quot;&gt;Evan Weaver&lt;/a&gt; has posted two really useful things for Facebook and Ruby on Rails. &lt;a href=&quot;http://blog.evanweaver.com/articles/2007/07/12/see-your-hand-in-front-of-your-uh-face-facebook_exceptions&quot;&gt;First&lt;/a&gt; a way to output the Facebook exceptions nicely when viewing in Facebook and &lt;a href=&quot;http://blog.evanweaver.com/articles/2007/07/13/developing-a-facebook-app-locally&quot;&gt;Second&lt;/a&gt; how to develop an application locally while tunneling from a server Facebook can see.&lt;/p&gt;


	&lt;h2&gt;Sending events to the feed.&lt;/h2&gt;


	&lt;p&gt;One of the features that makes Facebook so great is the powerful News Feed&#8217;s and mini-feed which keeps you updated on what&#8217;s going on with your friend&#8217;s lifes and in-touch with your application content. The Facebook &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; allows you to do two things with the feed. You can publish a &lt;a href=&quot;http://developers.facebook.com/documentation.php?v=1.0&amp;amp;#38;method=feed.publishStoryToUser&quot;&gt;News Feed story to just the user logged in&lt;/a&gt; with&lt;/p&gt;


&lt;pre&gt;
    &lt;code class=&quot;ruby&quot;&gt;
fbsession.feed_publishStoryToUser(:title =&amp;gt; &quot;&quot;, :body =&amp;gt; &quot;&quot;, :image_1 =&amp;gt; &quot;&quot;)
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;or &lt;a href=&quot;http://developers.facebook.com/documentation.php?v=1.0&amp;amp;#38;method=feed.publishActionOfUser&quot;&gt;publish a Mini-Feed story to the user and a News Feed story to their friends&lt;/a&gt; with&lt;/p&gt;


&lt;pre&gt;
    &lt;code class=&quot;ruby&quot;&gt;
fbsession.feed_publishActionOfUser(:title =&amp;gt; &quot;&quot;, :body =&amp;gt; &quot;&quot;, :image_1 =&amp;gt; &quot;&quot;)
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;In both cases you can publish up to four images in the story with will be strung to a 75&#215;75 square by Facebook and cached and served by them. Additionally the stories may not show up depending on the quality of the other competing stories in the feed! Applications are also limited to calling  &lt;strong&gt;feed_publishStoryToUser&lt;/strong&gt; once every 12 hours for each user and &lt;strong&gt;feed_publishActionOfUser&lt;/strong&gt; to 10 times in 48 hours for each user.&lt;/p&gt;


	&lt;p&gt;Now to our application. We are going to notify the user and all their friends when they create a new recipe so all their friends can go check it out and cook it. So in &lt;strong&gt;recipes_controller&lt;/strong&gt; and the &lt;strong&gt;create&lt;/strong&gt; action.&lt;/p&gt;


&lt;pre&gt;
    &lt;code class=&quot;ruby&quot;&gt;
if @recipe.save

  fbsession.feed_publishActionOfUser(:title =&amp;gt; &quot;&amp;lt;fb:name/&amp;gt; 
  has added a recipe for &amp;lt;a href=\&quot;http://apps.facebook.com#{url_for(:controller =&amp;gt; 'recipes', :action =&amp;gt; 'show', :id =&amp;gt; @recipe, :only_path =&amp;gt; true)}\&quot; &amp;gt;#{@recipe.title}&amp;lt;/a&amp;gt;&quot;, 
   :body =&amp;gt; &quot;#{@recipe.summary}&quot;)
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;In this case we use a &lt;strong&gt;url_for&lt;/strong&gt; to add the &lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt; to an absolute path. This is necessary for Facebook as all links on the pages outside your application must be absolute. We also have used a little &lt;span class=&quot;caps&quot;&gt;FBML&lt;/span&gt; to display the user&#8217;s name in the news feeds.&lt;/p&gt;


	&lt;p&gt;Now it would be great if we could use observations on ActiveRecord models to do this but the &lt;strong&gt;fbsession&lt;/strong&gt; is available only in the controllers, a limit of &lt;strong&gt;rfacebook&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;&lt;img src=&quot;http://www.liverail.net/assets/2007/7/16/Picture_1.png&quot;&gt;&lt;/img&gt;&lt;/p&gt;


	&lt;h2&gt;Adding a profile box to a user&#8217;s profile page&lt;/h2&gt;


	&lt;p&gt;The profile box is a little mini-view of your application which is on a user&#8217;s profile page The quirk behind profile boxes is the don&#8217;t send a request to your application to display the content. Instead you must set what content (in &lt;span class=&quot;caps&quot;&gt;FBML&lt;/span&gt;) will appear in your application box for each user. This is a push method rather than a pull method. &lt;a href=&quot;http://wiki.developers.facebook.com/index.php/Random_Questions#Basic_Application_Architecture&quot;&gt;More information here&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;So when do you actually set the profile box content. Well it depends what you are putting in the box, if you are just updating it with information about the users data then you may want to update that users profile box after a certain event. If you have information from a users friends data you may need to update a users profile box and update any of their friends after a certain event.&lt;/p&gt;


	&lt;p&gt;In our case the profile box is going to contain just a list of the recipes a user has added, but we are going to keep it keep generic. Try adding this to the ApplicationController&lt;/p&gt;


&lt;pre&gt;
    &lt;code class=&quot;ruby&quot;&gt;
def update_profile(uid = fbsession.session_user_id)
  #find the user specific recipes
  recipes = Recipe.find_my_recipes(uid)

  #render a partial to a string
  profile_box = render_to_string(:partial =&amp;gt; 'users/profile_fbml', :locals =&amp;gt; { :uid =&amp;gt; uid, :recipes =&amp;gt; recipes })

  #send the profile FBML to Facebook through the API for this user
  fbsession.profile_setFBML({:markup =&amp;gt; profile_box, :uid =&amp;gt; uid})
end
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;We can then call &lt;strong&gt;update_profile&lt;/strong&gt; from any controller to update a users profile, by default it will update the current user but we can override this to say update a friends profile.&lt;/p&gt;


	&lt;p&gt;For the partail we need to create &lt;strong&gt;app/views/users/_profile_fbml.rhtml&lt;/strong&gt;&lt;/p&gt;


&lt;pre&gt;
    &lt;code class=&quot;ruby&quot;&gt;
&amp;lt;fb:if-is-own-profile&amp;gt;
  &amp;lt;fb:subtitle&amp;gt;You have created &amp;lt;%=pluralize(recipes.size, 'recipe')%&amp;gt;&amp;lt;/fb:subtitle&amp;gt;
  &amp;lt;fb:else&amp;gt;
   &amp;lt;fb:subtitle&amp;gt;
    &amp;lt;fb:name uid=&quot;&amp;lt;%=uid%&amp;gt;&quot;/&amp;gt; has created &amp;lt;%=pluralize(recipes.size, 'recipe')%&amp;gt;
   &amp;lt;/fb:subtitle&amp;gt;
  &amp;lt;/fb:else&amp;gt;
&amp;lt;/fb:if-is-own-profile&amp;gt;
&amp;lt;%recipes.each do |recipe| %&amp;gt;
  &amp;lt;div&amp;gt;
    &amp;lt;h2&amp;gt;&amp;lt;a href=&quot;http://apps.facebook.com&amp;lt;%= url_for :controller =&amp;gt; 'recipes', :action =&amp;gt; 'show', :id =&amp;gt; recipe%&amp;gt;&quot;&amp;gt;
    &amp;lt;%=h(recipe.title)%&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/h2&amp;gt;
    &amp;lt;p&amp;gt;&amp;lt;%=h recipe.summary %&amp;gt;&amp;lt;/p&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;%end%&amp;gt;

&amp;lt;fb:if-is-app-user&amp;gt;
&amp;lt;fb:else&amp;gt;&amp;lt;a href=&quot;http://www.facebook.com/add.php?api_key=28e9f67df073c92829aa003e6762e074&quot;&amp;gt;
    Add Social Recipe for yourself&amp;lt;/a&amp;gt;&amp;lt;/fb:else&amp;gt;
&amp;lt;/fb:if-is-app-user&amp;gt;
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;This &lt;span class=&quot;caps&quot;&gt;FBML&lt;/span&gt; code works in two ways, first if the user is viewing there own profile it says &lt;em&gt;You have created&lt;/em&gt; but if someone else if viewing their profile it says &lt;em&gt;Stuart Eccles has created&lt;/em&gt; for instance. We then link to the recipes, note the use of absolute URLs, a must on the profile box. Finally if another user has not added the application we chuck in a sneaky plug to our application. Note the api_key you will want to move this to a constant.&lt;/p&gt;


	&lt;p&gt;Finally we need to call the update_user and we will do so after a create or delete action on a controller i.e.&lt;/p&gt;


&lt;pre&gt;
    &lt;code class=&quot;ruby&quot;&gt;
def update
  @recipe = Recipe.find(params[:id])

  if @recipe.update_attributes(params[:recipe])
   flash[:notice] = 'Recipe was successfully updated.'

   update_profile
   redirect_to :action =&amp;gt; 'show', :id =&amp;gt; @recipe
  else
   render :action =&amp;gt; &quot;edit&quot; 
  end
end
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;&lt;img src=&quot;http://www.liverail.net/assets/2007/7/16/Picture_2.png&quot;&gt;&lt;/img&gt;&lt;/p&gt;


	&lt;h2&gt;Adding a profile action to a user&#8217;s profile page&lt;/h2&gt;


	&lt;p&gt;A profile action appears as a link just under a users picture on their profile. The profile action link should be set at the same time as the profile box so to add a link we just need to add a bit of &lt;span class=&quot;caps&quot;&gt;FBML&lt;/span&gt; to the end of the &lt;strong&gt;_profile_fbml.rhtml&lt;/strong&gt;&lt;/p&gt;


&lt;pre&gt;
    &lt;code class=&quot;ruby&quot;&gt;
&amp;lt;fb:if-is-own-profile&amp;gt;
&amp;lt;fb:profile-action url=&quot;http://apps.facebook.com&amp;lt;%= url_for :controller =&amp;gt; 'recipes', :action =&amp;gt; 'my'%&amp;gt;&quot;&amp;gt;
View My Recipes (&amp;lt;%=recipes.size%&amp;gt;)
&amp;lt;/fb:profile-action&amp;gt;
&amp;lt;fb:else&amp;gt;
&amp;lt;fb:profile-action url=&quot;http://apps.facebook.com&amp;lt;%= url_for :controller =&amp;gt; 'recipes', :action =&amp;gt; 'index'%&amp;gt;&quot;&amp;gt;
View &amp;lt;fb:pronoun uid=&quot;&amp;lt;%=uid%&amp;gt;&quot; possessive=&quot;true&quot; capitalize=&quot;true&quot;/&amp;gt; Recipes (&amp;lt;%=recipes.size%&amp;gt;)
&amp;lt;/fb:else&amp;gt;
&amp;lt;/fb:profile-action&amp;gt;
&amp;lt;/fb:if-is-own-profile&amp;gt;
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;Again it gets switched depending on if the user is viewing their profile or someone else. If it is someone else we use the &lt;strong&gt;fb:pronoun&lt;/strong&gt; to output His or Her.&lt;/p&gt;


	&lt;p&gt;&lt;img src=&quot;http://www.liverail.net/assets/2007/7/16/Picture_3.png&quot;&gt;&lt;/img&gt;&lt;/p&gt;


	&lt;h2&gt;Adding an application invitation&lt;/h2&gt;


	&lt;p&gt;Our application is so cool no your users are going to want to share it with their friends (well yours will be, this tutorial application lacks coolness). So lets allow users to invite their friends.&lt;/p&gt;


	&lt;p&gt;We only want people to be inviting their friends how havn&#8217;t already added the application, unfortunately we don&#8217;t have an &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; call for this. Fortunately there is a way around this but we have to use the &lt;a href=&quot;http://developers.facebook.com/documentation.php?v=1.0&amp;amp;#38;doc=fql&quot;&gt;Facebook Query Language&lt;/a&gt; which is just like a select &lt;span class=&quot;caps&quot;&gt;SQL&lt;/span&gt; statement. We can select data from the &lt;em&gt;user&lt;/em&gt;, &lt;em&gt;friend&lt;/em&gt;, &lt;em&gt;group&lt;/em&gt;, &lt;em&gt;group_member&lt;/em&gt;, &lt;em&gt;event&lt;/em&gt;, &lt;em&gt;event_member&lt;/em&gt;, &lt;em&gt;photo&lt;/em&gt;, &lt;em&gt;album&lt;/em&gt;, &lt;em&gt;photo_tag&lt;/em&gt; tables. We can then call the &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; through &lt;strong&gt;fql_query&lt;/strong&gt; method on &lt;strong&gt;fbsession&lt;/strong&gt;, this will return &lt;span class=&quot;caps&quot;&gt;XML&lt;/span&gt; we can then parse. You can try out your &lt;span class=&quot;caps&quot;&gt;FQL&lt;/span&gt; first at the &lt;a href=&quot;http://developers.facebook.com/tools.php&quot;&gt;test console&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;We need to create an invites controller:&lt;/p&gt;


&lt;pre&gt;
    &lt;code class=&quot;console&quot;&gt;
script/generate controller invites         
    &lt;/code&gt;
&lt;/pre&gt;

&lt;pre&gt;
    &lt;code class=&quot;ruby&quot;&gt;
class InvitesController &amp;lt; ApplicationController

  def select
    fql =  &quot;SELECT uid, name FROM user WHERE uid IN&quot; +
    &quot;(SELECT uid2 FROM friend WHERE uid1 = #{@current_fb_user_id}) &quot; +
    &quot;AND has_added_app = 0&quot; 
    xml_friends = fbsession.fql_query :query =&amp;gt; fql
    @friends = Hash.new
    xml_friends.search(&quot;//user&quot;).map do|usrNode| 
      @friends[(usrNode/&quot;uid&quot;).inner_html] = (usrNode/&quot;name&quot;).inner_html
    end
    render_facebook
  end

end
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;In this code we select friends of the current user where the friends &lt;strong&gt;has_added_app = 0&lt;/strong&gt; so therefore are not using the application. We then parse their names and uids into a hash. Lets create two outputs for this list, a normal &lt;span class=&quot;caps&quot;&gt;HTML&lt;/span&gt; one and an &lt;span class=&quot;caps&quot;&gt;FBML&lt;/span&gt; one.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;app/views/invites/select.rhtml&lt;/strong&gt;&lt;/p&gt;


&lt;pre&gt;
    &lt;code class=&quot;html&quot;&gt;
&amp;lt;% form_tag :action =&amp;gt; 'send_invites' do -%&amp;gt;
&amp;lt;ul&amp;gt;
&amp;lt;% @friends.each do |uid,name|%&amp;gt;
     &amp;lt;li&amp;gt;&amp;lt;input type=&quot;checkbox&quot; name=&quot;friends[]&quot; value=&quot;&amp;lt;%=uid%&amp;gt;&quot;/&amp;gt; &amp;lt;%=name%&amp;gt;&amp;lt;/li&amp;gt;
&amp;lt;%end%&amp;gt;
&amp;lt;/ul&amp;gt;

You can only invite a maximum of ten people at once.
&amp;lt;input type=&quot;submit&quot; value=&quot;Invite&quot;/&amp;gt;
&amp;lt;% end -%&amp;gt;
    &lt;/code&gt;
&lt;/pre&gt;

&lt;strong&gt;app/views/invites/select_fbml.rhtml&lt;/strong&gt;
&lt;pre&gt;
    &lt;code class=&quot;html&quot;&gt;
&amp;lt;% form_tag :action =&amp;gt; 'send_invites' do -%&amp;gt;
&amp;lt;ul&amp;gt;
&amp;lt;% @friends.each do |uid,name|%&amp;gt;
     &amp;lt;li&amp;gt;&amp;lt;input type=&quot;checkbox&quot; name=&quot;friends[]&quot; value=&quot;&amp;lt;%=uid%&amp;gt;&quot;/&amp;gt;&amp;lt;fb:profile-pic uid=&quot;&amp;lt;%= uid %&amp;gt;&quot; size=&quot;thumb&quot; /&amp;gt; &amp;lt;%=name%&amp;gt;&amp;lt;/li&amp;gt;
&amp;lt;%end%&amp;gt;
&amp;lt;/ul&amp;gt;

You can only invite a maximum of ten people at once.
&amp;lt;input type=&quot;submit&quot; value=&quot;Invite&quot;/&amp;gt;
&amp;lt;% end -%&amp;gt;
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;&lt;img src=&quot;http://www.liverail.net/assets/2007/7/16/Picture_5.png&quot;&gt;&lt;/img&gt;&lt;/p&gt;


	&lt;p&gt;The only difference is in the &lt;span class=&quot;caps&quot;&gt;FBML&lt;/span&gt; version we have outputted a picture. You can style this in table or any way you want really but Facebook will only let you send 10 notifications at once and only 20 a day for each user. Now we need the &lt;strong&gt;send_invites&lt;/strong&gt; action added to the controller&lt;/p&gt;


&lt;pre&gt;
    &lt;code class=&quot;ruby&quot;&gt;
      def send_invites
        invite = render_to_string(:partial =&amp;gt; 'invites/invite_fbml', :locals =&amp;gt; { :inviter =&amp;gt; @current_fb_user_id })

        friends = params[:friends]
        if friends.is_a? String
          invitees = friends
        else
          invitees = friends.values.join(&quot;,&quot;)
        end

        result_xml = fbsession.notifications_sendRequest(:to_ids =&amp;gt; invitees, :type =&amp;gt; 'Social Recipe', :content =&amp;gt; invite, :invite =&amp;gt; true, :image =&amp;gt; &quot;http://apps.facebook.com/socialrecipe/P1010825_tiny.jpg&quot;)

        response = CGI.unescapeHTML((result_xml/&quot;notifications_sendrequest_response&quot;).inner_html)

        if response =~ /^(http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$/ix
          #need to do a confirmation redirect
          if in_facebook_canvas?
            render :text =&amp;gt; &quot;&amp;lt;fb:redirect url=\&quot;#{response}\&quot;/&amp;gt;&quot;, :layout =&amp;gt; false
          else
            redirect_to response
          end
        else
          flash[:notice] = 'Invites sent.'
          redirect_to :controller =&amp;gt; 'recipes', :action =&amp;gt; 'index'
        end
      end
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;Similar to the profile box we are using a partial with &lt;strong&gt;render_to_string&lt;/strong&gt; to create the &lt;span class=&quot;caps&quot;&gt;FBML&lt;/span&gt; to send in the notification. We pass in the inviter uid to use as a local in the partial. Note that the image parameter is required in the &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; call even if you don&#8217;t have an image to show! Once we have a response from the &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; call we will either be returned a &lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt; to redirect the user to confirm the notification or it will return nothing at all. The redirect has to be handled in different way depending on if you are in the canvas, if you are you need to output the &lt;strong&gt;fb:redirect&lt;/strong&gt; tag.&lt;/p&gt;


	&lt;p&gt;If it returns nothing if either means no confirmation is necessary and the notification was sent or there was an error&#8230;.. hmmmm lets be optimistic and say it was sent shall we.&lt;/p&gt;


&lt;pre&gt;
    &lt;code class=&quot;html&quot;&gt;
You have been invited to upload your recipes to Social Recipe! 
&amp;lt;fb:name uid=&quot;&amp;lt;%= inviter%&amp;gt;&quot; firstnameonly=&quot;false&quot; shownetwork=&quot;false&quot;/&amp;gt; wants you to add Social Recipes so you can share recipes together
&amp;lt;fb:req-choice url=&quot;http://www.facebook.com/add.php?api_key=916c58dd4fba835cc43389a432fa98d0&quot; label=&quot;Add&quot; /&amp;gt;
&amp;lt;fb:req-choice url=&quot;http://apps.facebook.com/socialrecipe&quot; label=&quot;Go to Application&quot; /&amp;gt;
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;The &lt;strong&gt;fb:req-choice&lt;/strong&gt; will give the user in the notification the options to add the application or go to it. If you now submit the form&lt;/p&gt;


	&lt;p&gt;&lt;img src=&quot;http://www.liverail.net/assets/2007/7/16/Picture_6.png&quot;&gt;&lt;/img&gt;&lt;/p&gt;


	&lt;h2&gt;Wrapup&lt;/h2&gt;


	&lt;p&gt;So that&#8217;s all, there are a few more things to discover in the application interface but you should have all the basic elements to create some fun apps to share with your friends and their friends. There is certainly not enough error handling in here for a production application but i&#8217;ll leave that up to the reader.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.liverail.net/">
    <author>
      <name>stuarteccles</name>
    </author>
    <id>tag:www.liverail.net,2007-06-29:1909</id>
    <published>2007-06-29T12:25:00Z</published>
    <updated>2008-02-15T11:52:52Z</updated>
    <category term="Facebook"/>
    <category term="RubyOnRails"/>
    <category term="facebook"/>
    <category term="rails"/>
    <category term="Rails"/>
    <category term="rfacebook"/>
    <category term="ruby"/>
    <link href="http://www.liverail.net/articles/2007/6/29/tutorial-on-developing-a-facebook-platform-application-with-ruby-on-rails" rel="alternate" type="text/html"/>
    <title>Tutorial on developing a Facebook platform application with Ruby On Rails</title>
<summary type="html">&lt;p&gt;If you havn&#8217;t heard of &lt;a href=&quot;http://www.facebook.com/&quot;&gt;Facebook&lt;/a&gt;. Where you been, living in a cave! Well you also probably know that in June 2007 Facebook opened a &lt;a href=&quot;http://developers.facebook.com/&quot;&gt;development platform&lt;/a&gt; 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 &lt;a href=&quot;http://www.techcrunch.com/2007/05/24/facebook-launches-facebook-platform-they-are-the-anti-myspace/&quot;&gt;online&lt;/a&gt; and &lt;a href=&quot;http://www.guardian.co.uk/travel/2007/jun/23/saturday.bestofthenet&quot;&gt;traditional&lt;/a&gt; news media, Facebook have changed the game.&lt;/p&gt;


	&lt;p&gt;Well ZDNet are reporting that &lt;a href=&quot;http://www.zdnet.com.au/news/software/soa/FaceBook-platform-attracts-1-000-developers-a-day/0,130061733,339278661,00.htm&quot;&gt;1,000 developers a day&lt;/a&gt; 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.&lt;/p&gt;


	&lt;p&gt;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.&lt;/p&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;UPDATE&lt;/span&gt;: The second part can be found &lt;a href=&quot;http://www.liverail.net/articles/2007/7/16/continuing-facebook-applications-with-ruby-on-rails&quot;&gt;here&lt;/a&gt;&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;If you havn&#8217;t heard of &lt;a href=&quot;http://www.facebook.com/&quot;&gt;Facebook&lt;/a&gt;. Where you been, living in a cave! Well you also probably know that in June 2007 Facebook opened a &lt;a href=&quot;http://developers.facebook.com/&quot;&gt;development platform&lt;/a&gt; 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 &lt;a href=&quot;http://www.techcrunch.com/2007/05/24/facebook-launches-facebook-platform-they-are-the-anti-myspace/&quot;&gt;online&lt;/a&gt; and &lt;a href=&quot;http://www.guardian.co.uk/travel/2007/jun/23/saturday.bestofthenet&quot;&gt;traditional&lt;/a&gt; news media, Facebook have changed the game.&lt;/p&gt;


	&lt;p&gt;Well ZDNet are reporting that &lt;a href=&quot;http://www.zdnet.com.au/news/software/soa/FaceBook-platform-attracts-1-000-developers-a-day/0,130061733,339278661,00.htm&quot;&gt;1,000 developers a day&lt;/a&gt; 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.&lt;/p&gt;


	&lt;p&gt;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.&lt;/p&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;UPDATE&lt;/span&gt;: The second part can be found &lt;a href=&quot;http://www.liverail.net/articles/2007/7/16/continuing-facebook-applications-with-ruby-on-rails&quot;&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If you havn&#8217;t heard of &lt;a href=&quot;http://www.facebook.com/&quot;&gt;Facebook&lt;/a&gt;. Where you been, living in a cave! Well you also probably know that in June 2007 Facebook opened a &lt;a href=&quot;http://developers.facebook.com/&quot;&gt;development platform&lt;/a&gt; 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 &lt;a href=&quot;http://www.techcrunch.com/2007/05/24/facebook-launches-facebook-platform-they-are-the-anti-myspace/&quot;&gt;online&lt;/a&gt; and &lt;a href=&quot;http://www.guardian.co.uk/travel/2007/jun/23/saturday.bestofthenet&quot;&gt;traditional&lt;/a&gt; news media, Facebook have changed the game.&lt;/p&gt;


	&lt;p&gt;Well ZDNet are reporting that &lt;a href=&quot;http://www.zdnet.com.au/news/software/soa/FaceBook-platform-attracts-1-000-developers-a-day/0,130061733,339278661,00.htm&quot;&gt;1,000 developers a day&lt;/a&gt; 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.&lt;/p&gt;


	&lt;p&gt;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.&lt;/p&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;UPDATE&lt;/span&gt;: The second part can be found &lt;a href=&quot;http://www.liverail.net/articles/2007/7/16/continuing-facebook-applications-with-ruby-on-rails&quot;&gt;here&lt;/a&gt;&lt;/p&gt;


First of all some useful links:
	&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;http://developers.facebook.com/&quot;&gt;Facebook Developers&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;http://developers.facebook.com/documentation.php&quot;&gt;Facebook Documentation&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;http://wiki.developers.facebook.com/index.php/Main_Page&quot;&gt;Facebook Developers Wiki&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;http://facebook.jdg.net/&quot;&gt;Ruby On Rails Facebook Application Forum&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Facebook has provided many different integration points and different APIs to an application so it is worth reading &lt;a href=&quot;http://developers.facebook.com/anatomy.php&quot;&gt;Anatomy of a Facebook Application&lt;/a&gt; first which will explain the areas an application can affect for a user.&lt;/p&gt;


There are two different types of Facebook application
	&lt;ol&gt;
	&lt;li&gt;A desktop application&lt;/li&gt;
		&lt;li&gt;A website application&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;We are only going to be concerned with website applications for now. There is also 3 different ways an application can interact with Facebook.&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;As an external application but interacting with the remote &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt;&lt;/li&gt;
		&lt;li&gt;Running in an &lt;span class=&quot;caps&quot;&gt;IFRAME&lt;/span&gt; on the Facebook site&lt;/li&gt;
		&lt;li&gt;Running in a Facebook canvas and using Facebook Markup Language (FBML)&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;The application can use one or all of these techniques. We are going to try all three in this tutorial.&lt;/p&gt;


	&lt;p&gt;But first lets start by creating a Rails application with NO Facebook stuff and then we&#8217;ll look at FB-ing it. Originally I planned to do this completely RESTfully but it turns out it doesn&#8217;t work well with Facebook canvas, so it&#8217;s old-skool Rails i&#8217;m afraid.&lt;/p&gt;


	&lt;p&gt;Lets create the application:&lt;/p&gt;


&lt;pre&gt;
    &lt;code class=&quot;console&quot;&gt;
rails socialrecipe

cd socialrecipe
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;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)&lt;/p&gt;


&lt;pre&gt;
    &lt;code class=&quot;console&quot;&gt;
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
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;Lets create our databases. I&#8217;m using MySQL&lt;/p&gt;


&lt;pre&gt;
    &lt;code class=&quot;console&quot;&gt;
sudo mysqladmin create socialrecipe_development
sudo mysqladmin create socialrecipe_test
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;Lets changed to using database sessions. Now edit &lt;strong&gt;config/environment.rb&lt;/strong&gt; change the Rails Initializer section and uncomment the following line&lt;/p&gt;


&lt;pre&gt;
    &lt;code class=&quot;ruby&quot;&gt;
config.action_controller.session_store = :active_record_store
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;And add a line at the end of &lt;strong&gt;config/environment.rb&lt;/strong&gt;&lt;/p&gt;


&lt;pre&gt;
    &lt;code class=&quot;ruby&quot;&gt;
ActionController::AbstractRequest.relative_url_root = &quot;/socialrecipe&quot; 
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;What this does is change the Rails application to run starting with a &lt;em&gt;socialrecipe&lt;/em&gt; in the first part of the &lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt;. We need this for later but you will need your own unique name (i&#8217;m using socialrecipe). So think of one and take note.&lt;/p&gt;


	&lt;p&gt;Now lets create our development database.&lt;/p&gt;


&lt;pre&gt;
    &lt;code class=&quot;console&quot;&gt;
rake db:sessions:create

rake db:migrate
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;Now lets create our controllers&lt;/p&gt;


&lt;pre&gt;
    &lt;code class=&quot;console&quot;&gt;
ruby script/generate controller recipes 
ruby script/generate controller comments
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;Excellent. Now lets change our model definitions so that Recipes can have many comments. Edit &lt;strong&gt;app/models/recipe.rb&lt;/strong&gt; to&lt;/p&gt;


&lt;pre&gt;
    &lt;code class=&quot;ruby&quot;&gt;
class Recipe &amp;lt; ActiveRecord::Base
    has_many :comments

    validates_presence_of :title, :summary, :ingredients, :instructions
end
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;And edit &lt;strong&gt;models/comment.rb&lt;/strong&gt; to&lt;/p&gt;


&lt;pre&gt;
    &lt;code class=&quot;ruby&quot;&gt;
class Comment &amp;lt; ActiveRecord::Base
    belongs_to :recipe

    validates_presence_of :body, :recipe_id

end
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;Now lets add the controller for the recipe. Edit &lt;strong&gt;app/controllers/recipes_controller.rb&lt;/strong&gt; and change it to&lt;/p&gt;


&lt;pre&gt;
    &lt;code class=&quot;ruby&quot;&gt;
class RecipesController &amp;lt; ApplicationController

  def index
    @recipes = Recipe.find(:all)
    @title = &quot;All recipes&quot; 
  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 =&amp;gt; 'show', :id =&amp;gt; @recipe
    else
      render :action =&amp;gt; &quot;new&quot; 
    end

  end

  def update
    @recipe = Recipe.find(params[:id])

    if @recipe.update_attributes(params[:recipe])
      flash[:notice] = 'Recipe was successfully updated.'
      redirect_to :action =&amp;gt; 'show', :id =&amp;gt; @recipe
    else
      render :action =&amp;gt; &quot;edit&quot; 
    end
  end

end
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;Edit &lt;strong&gt;app/controllers/comments_controller.rb&lt;/strong&gt; and change it to&lt;/p&gt;


&lt;pre&gt;
    &lt;code class=&quot;ruby&quot;&gt;
class CommentsController &amp;lt; 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 =&amp;gt; 'recipes', :action =&amp;gt; 'show', :id =&amp;gt; @comment.recipe
    else
      render_action 'new' 
    end
  end
end
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;Pretty standard stuff so far creating simple controllers to create, read and update recipes and create comments. Lets setup the views&lt;/p&gt;


	&lt;p&gt;Add &lt;strong&gt;app/views/recipes/index.rhtml&lt;/strong&gt; with&lt;/p&gt;


&lt;pre&gt;
    &lt;code class=&quot;ruby&quot;&gt;
&amp;lt;h2&amp;gt;&amp;lt;%= @title %&amp;gt;&amp;lt;/h2&amp;gt;

&amp;lt;%@recipes.each do |recipe|%&amp;gt;
&amp;lt;div&amp;gt;
&amp;lt;h3&amp;gt;&amp;lt;%= link_to h(recipe.title), :controller =&amp;gt; 'recipes', :action =&amp;gt; 'show', :id =&amp;gt; recipe%&amp;gt;&amp;lt;/h3&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;%=h recipe.summary %&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;%end%&amp;gt;

&amp;lt;br/&amp;gt;
&amp;lt;%= link_to 'New recipe', :controller =&amp;gt; 'recipes', :action =&amp;gt; 'new' %&amp;gt;
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;Add &lt;strong&gt;app/views/recipes/new.rhtml&lt;/strong&gt; with&lt;/p&gt;


&lt;pre&gt;
    &lt;code class=&quot;ruby&quot;&gt;
        &amp;lt;h1&amp;gt;New recipe&amp;lt;/h1&amp;gt;

        &amp;lt;%= error_messages_for :recipe %&amp;gt;

        &amp;lt;% form_for(:recipe, :url =&amp;gt; {:controller =&amp;gt; 'recipes', :action =&amp;gt; 'create'}) do |f| %&amp;gt;
          &amp;lt;dl&amp;gt;
              &amp;lt;dt&amp;gt;&amp;lt;label for=&quot;recipe_title&quot;&amp;gt;Title:&amp;lt;/label&amp;gt;&amp;lt;/dt&amp;gt;
            &amp;lt;dd&amp;gt;&amp;lt;%= f.text_field :title %&amp;gt;&amp;lt;/dd&amp;gt;
            &amp;lt;dt&amp;gt;&amp;lt;label for=&quot;recipe_summary&quot;&amp;gt;Summary:&amp;lt;/label&amp;gt;&amp;lt;/dt&amp;gt;
            &amp;lt;dd&amp;gt;&amp;lt;%= f.text_area :summary %&amp;gt;&amp;lt;/dd&amp;gt;
            &amp;lt;dt&amp;gt;&amp;lt;label for=&quot;recipe_ingredients&quot;&amp;gt;Ingredients:&amp;lt;/label&amp;gt;&amp;lt;/dt&amp;gt;
            &amp;lt;dd&amp;gt;&amp;lt;%= f.text_area :ingredients %&amp;gt;&amp;lt;/dd&amp;gt;
            &amp;lt;dt&amp;gt;&amp;lt;label for=&quot;recipe_instructions&quot;&amp;gt;Cooking Instructions:&amp;lt;/label&amp;gt;&amp;lt;/dt&amp;gt;
            &amp;lt;dd&amp;gt;&amp;lt;%= f.text_area :instructions %&amp;gt;&amp;lt;/dd&amp;gt;
            &amp;lt;dt&amp;gt;&amp;lt;label for=&quot;recipe_cooking_time&quot;&amp;gt;Cooking Time:&amp;lt;/label&amp;gt;&amp;lt;/dt&amp;gt;
            &amp;lt;dd&amp;gt;&amp;lt;%= f.text_field :cooking_time %&amp;gt; mins&amp;lt;/dd&amp;gt;
            &amp;lt;dt&amp;gt;&amp;lt;/dt&amp;gt;
            &amp;lt;dd&amp;gt;&amp;lt;%= submit_tag &quot;Create&quot; %&amp;gt;&amp;lt;/dd&amp;gt;
          &amp;lt;/dl&amp;gt;
        &amp;lt;% end %&amp;gt;

        &amp;lt;br/&amp;gt;
        &amp;lt;%= link_to 'Back', :controller =&amp;gt; 'recipes' %&amp;gt;
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;The use of &lt;em&gt;dl&lt;/em&gt; tags for forms is not a facebook thing. It&#8217;s just the way I rock it.&lt;/p&gt;


	&lt;p&gt;Add &lt;strong&gt;app/views/recipes/edit.rhtml&lt;/strong&gt; with&lt;/p&gt;


&lt;pre&gt;
    &lt;code class=&quot;ruby&quot;&gt;
&amp;lt;h1&amp;gt;Editing recipe&amp;lt;/h1&amp;gt;

&amp;lt;%= error_messages_for :recipe %&amp;gt;

&amp;lt;% form_for(:recipe, 
      :url =&amp;gt; {:controller =&amp;gt;'recipes', :action =&amp;gt; 'update', :id =&amp;gt; @recipe}) do |f| %&amp;gt;
&amp;lt;dl&amp;gt;
    &amp;lt;dt&amp;gt;&amp;lt;label for=&quot;recipe_title&quot;&amp;gt;Title:&amp;lt;/label&amp;gt;&amp;lt;/dt&amp;gt;
    &amp;lt;dd&amp;gt;&amp;lt;%= f.text_field :title %&amp;gt;&amp;lt;/dd&amp;gt;
    &amp;lt;dt&amp;gt;&amp;lt;label for=&quot;recipe_summary&quot;&amp;gt;Summary:&amp;lt;/label&amp;gt;&amp;lt;/dt&amp;gt;
    &amp;lt;dd&amp;gt;&amp;lt;%= f.text_area :summary %&amp;gt;&amp;lt;/dd&amp;gt;
    &amp;lt;dt&amp;gt;&amp;lt;label for=&quot;recipe_ingredients&quot;&amp;gt;Ingredients:&amp;lt;/label&amp;gt;&amp;lt;/dt&amp;gt;
    &amp;lt;dd&amp;gt;&amp;lt;%= f.text_area :ingredients %&amp;gt;&amp;lt;/dd&amp;gt;
    &amp;lt;dt&amp;gt;&amp;lt;label for=&quot;recipe_instructions&quot;&amp;gt;Cooking Instructions:&amp;lt;/label&amp;gt;&amp;lt;/dt&amp;gt;
    &amp;lt;dd&amp;gt;&amp;lt;%= f.text_area :instructions %&amp;gt;&amp;lt;/dd&amp;gt;
    &amp;lt;dt&amp;gt;&amp;lt;label for=&quot;recipe_cooking_time&quot;&amp;gt;Cooking Time:&amp;lt;/label&amp;gt;&amp;lt;/dt&amp;gt;
    &amp;lt;dd&amp;gt;&amp;lt;%= f.text_field :cooking_time %&amp;gt; mins&amp;lt;/dd&amp;gt;
    &amp;lt;dt&amp;gt;&amp;lt;/dt&amp;gt;
    &amp;lt;dd&amp;gt;&amp;lt;%= submit_tag &quot;Update&quot; %&amp;gt;&amp;lt;/dd&amp;gt;
&amp;lt;/dl&amp;gt;
&amp;lt;% end %&amp;gt;

&amp;lt;br/&amp;gt;
&amp;lt;%= link_to 'Show', :controller =&amp;gt; 'recipes', :action =&amp;gt; 'show', :id =&amp;gt;@recipe %&amp;gt; |
&amp;lt;%= link_to 'Back', :controller =&amp;gt; 'recipes' %&amp;gt;
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;Add &lt;strong&gt;app/views/recipes/show.rhtml&lt;/strong&gt; with&lt;/p&gt;


&lt;pre&gt;
    &lt;code class=&quot;ruby&quot;&gt;
&amp;lt;h1&amp;gt;&amp;lt;%=h @recipe.title %&amp;gt;&amp;lt;/h1&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;%=h @recipe.summary %&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;h2&amp;gt;Ingredients:&amp;lt;/h2&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;%=h @recipe.ingredients %&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;h2&amp;gt;Instructions:&amp;lt;/h2&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;%=h @recipe.instructions %&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;&amp;lt;em&amp;gt;Cooking time is around &amp;lt;%=h @recipe.cooking_time %&amp;gt; mins&amp;lt;/em&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;div id=&quot;comments&quot;&amp;gt;
    &amp;lt;h2&amp;gt;Displaying &amp;lt;%=pluralize(@recipe.comments.size, 'comment')%&amp;gt;&amp;lt;/h2&amp;gt;
    &amp;lt;%= link_to 'New comment', :controller =&amp;gt; 'comments', :action =&amp;gt; 'new', :recipe_id =&amp;gt; @recipe %&amp;gt;
       &amp;lt;% @recipe.comments.each do |comment| %&amp;gt;
           &amp;lt;div&amp;gt;
                &amp;lt;p&amp;gt;&amp;lt;%= comment.body %&amp;gt;&amp;lt;/p&amp;gt;    
                posted &amp;lt;%= time_ago_in_words(comment.created_at)  %&amp;gt; ago
            &amp;lt;/div&amp;gt;
       &amp;lt;%end %&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;br/&amp;gt;
&amp;lt;%= link_to 'Edit', :controller =&amp;gt; 'recipes', :action =&amp;gt; 'edit', :id =&amp;gt; @recipe %&amp;gt; |
&amp;lt;%= link_to 'Back', :controller =&amp;gt; 'recipes' %&amp;gt;
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;Add &lt;strong&gt;app/views/comments/new.rhtml&lt;/strong&gt; with&lt;/p&gt;


&lt;pre&gt;
    &lt;code class=&quot;ruby&quot;&gt;
&amp;lt;h1&amp;gt;New comment&amp;lt;/h1&amp;gt;

&amp;lt;%= error_messages_for :comment %&amp;gt;

&amp;lt;% form_for(:comment, :url =&amp;gt; 
      {:controller =&amp;gt; 'comments', :action =&amp;gt; 'create'}) do |f| %&amp;gt;
&amp;lt;dl&amp;gt;
    &amp;lt;dt&amp;gt;&amp;lt;label for=&quot;comment_body&quot;&amp;gt;Body Content:&amp;lt;/label&amp;gt;&amp;lt;/dt&amp;gt;
    &amp;lt;dd&amp;gt;&amp;lt;%= f.text_area :body %&amp;gt;&amp;lt;/dd&amp;gt;
    &amp;lt;dt&amp;gt;&amp;lt;/dt&amp;gt;
    &amp;lt;dd&amp;gt;&amp;lt;%= submit_tag &quot;Create&quot; %&amp;gt;&amp;lt;/dd&amp;gt;
&amp;lt;/dl&amp;gt;
    &amp;lt;%= f.hidden_field :recipe_id, :value =&amp;gt; @comment.recipe_id %&amp;gt;
&amp;lt;% end %&amp;gt;
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;And lets create a layout at &lt;strong&gt;app/views/layouts/index.rhtml&lt;/strong&gt;&lt;/p&gt;


&lt;pre&gt;
    &lt;code class=&quot;ruby&quot;&gt;
&amp;lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; 
       &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&amp;gt;

&amp;lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; xml:lang=&quot;en&quot; lang=&quot;en&quot;&amp;gt;
&amp;lt;head&amp;gt;
  &amp;lt;meta http-equiv=&quot;content-type&quot; content=&quot;text/html;charset=UTF-8&quot; /&amp;gt;
  &amp;lt;title&amp;gt;Recipes: &amp;lt;%= controller.action_name %&amp;gt;&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;p style=&quot;color: green&quot;&amp;gt;&amp;lt;%= flash[:notice] %&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;%= yield  %&amp;gt;

&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
    &lt;/code&gt;
&lt;/pre&gt;

and add this line to the &lt;strong&gt;app/controllers/application.rb&lt;/strong&gt;
&lt;pre&gt;
    &lt;code class=&quot;ruby&quot;&gt;
layout 'index'
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;change &lt;strong&gt;config/routes.rb&lt;/strong&gt; to have a default route&lt;/p&gt;


&lt;pre&gt;
    &lt;code class=&quot;ruby&quot;&gt;
map.connect '', :controller =&amp;gt; &quot;recipes&quot; 
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;and delete index.html from your public directory.
That&#8217;s it. We now have a simple (and very ugly application). Fire it up with &lt;strong&gt;script/server&lt;/strong&gt; and go to &lt;strong&gt;http://localhost:3000/socialrecipe&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;&lt;img src=&quot;http://www.liverail.net/assets/2007/6/29/Picture_1.png&quot; /&gt;&lt;/p&gt;


	&lt;p&gt;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.&lt;/p&gt;


&lt;pre&gt;
    &lt;code class=&quot;console&quot;&gt;
sudo gem install rfacebook -v 0.6.2        
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;Now you&#8217;ll need to log on to facebook (what do you mean you&#8217;re not on facebook!) and add the Developer application. Once you have done that press the big &#8220;Set Up New Application&#8221; button.&lt;/p&gt;


	&lt;p&gt;&lt;img src=&quot;http://www.liverail.net/assets/2007/6/29/Picture_2.png&quot; /&gt;&lt;/p&gt;


	&lt;p&gt;Now fill in the following fields&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Application Name:&lt;/strong&gt; 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.
&lt;strong&gt;Callback Url:&lt;/strong&gt; http://localhost:3000/socialrecipe/ (The end of this is the same as your relative_url_root)
&lt;strong&gt;Canvas Page &lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt;:&lt;/strong&gt; http://apps.facebook.com/ &lt;em&gt;socialrecipe&lt;/em&gt; (The field of this is the same as your relative_url_root)
Check Use iframe for now
&lt;strong&gt;Can your application be added on Facebook?&lt;/strong&gt; Yes
&lt;strong&gt;Post-Add &lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt;:&lt;/strong&gt; http://apps.facebook.com/socialrecipe/ (The end of this is the same as your relative_url_root)&lt;/p&gt;


	&lt;p&gt;That is all hit save and you should have a page listing your application with an &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; Key and a Secret. &lt;strong&gt;Make a note of your applications &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; Key and Secret&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;&lt;img src=&quot;http://www.liverail.net/assets/2007/6/29/Picture_4.png&quot; /&gt;&lt;/p&gt;


	&lt;p&gt;Now lets edit our rails application. Add the following to your ApplicationController in &lt;strong&gt;app/controllers/application.rb&lt;/strong&gt;&lt;/p&gt;


&lt;pre&gt;
    &lt;code class=&quot;ruby&quot;&gt;
before_filter :require_facebook_login, :set_user
include RFacebook::RailsControllerExtensions

def facebook_api_key
  return &quot;ADD YOUR API KEY HERE&quot; 
end

def facebook_api_secret
  return &quot;ADD YOUR SECRET HERE&quot; 
end

def finish_facebook_login
  redirect_to :controller =&amp;gt; &quot;recipes&quot; 
end

def set_user
  @current_fb_user_id = fbsession.session_user_id
end
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;and add the following to your &lt;strong&gt;config/environment.rb&lt;/strong&gt;&lt;/p&gt;


&lt;pre&gt;
    &lt;code class=&quot;ruby&quot;&gt;
require &quot;facebook_rails_controller_extensions&quot; 
    &lt;/code&gt;
&lt;/pre&gt;
You&#8217;ll see you need to add your own key and own secret to this. The &lt;strong&gt;set_user&lt;/strong&gt; 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 &lt;strong&gt;&lt;span class=&quot;caps&quot;&gt;BIGINT&lt;/span&gt;&lt;/strong&gt; if you are using MySQL. Facebook has &lt;span class=&quot;caps&quot;&gt;A LOT&lt;/span&gt; of users.

&lt;pre&gt;
    &lt;code class=&quot;console&quot;&gt;
script/generate migration add_fb_user_ids
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;Now edit &lt;strong&gt;db/migrate/004_add_fb_user_ids.rb&lt;/strong&gt; to:&lt;/p&gt;


&lt;pre&gt;
    &lt;code class=&quot;ruby&quot;&gt;
class AddFbUserIds &amp;lt; ActiveRecord::Migration
  def self.up
      add_column :recipes, :fb_user_id, :integer
      add_column :comments, :fb_user_id, :integer

      #if mysql
      execute(&quot;alter table recipes modify fb_user_id bigint&quot;)
      execute(&quot;alter table comments modify fb_user_id bigint&quot;)
  end

  def self.down
      remove_column :recipes, :fb_user_id
      remove_column :comments, :fb_user_id
  end
end
    &lt;/code&gt;
&lt;/pre&gt;

&lt;pre&gt;
    &lt;code class=&quot;console&quot;&gt;
rake db:migrate
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;We now need to store the facebook user ids in the tables so we&#8217;ll add a hidden field to the forms&lt;/p&gt;


	&lt;p&gt;Add the following to &lt;strong&gt;app/views/recipes/new.rhtml&lt;/strong&gt; and &lt;strong&gt;app/views/comments/new.rhtml&lt;/strong&gt; just before the end of the form&lt;/p&gt;


&lt;pre&gt;
    &lt;code class=&quot;ruby&quot;&gt;
&amp;lt;%= f.hidden_field :fb_user_id, :value =&amp;gt; @current_fb_user_id %&amp;gt;
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;We are also going to protect the edit recipe to only allow you to edit your own recipes
in &lt;strong&gt;app/views/recipes/show.rhtml&lt;/strong&gt; change&lt;/p&gt;


&lt;pre&gt;
    &lt;code class=&quot;ruby&quot;&gt;
    &amp;lt;%= link_to 'Edit', :controller =&amp;gt; 'recipes', :action =&amp;gt; 'edit', :id =&amp;gt; @recipe %&amp;gt; |
    &lt;/code&gt;
&lt;/pre&gt;

to
&lt;pre&gt;
    &lt;code class=&quot;ruby&quot;&gt;
&amp;lt;%is_my_recipe? @recipe do %&amp;gt;
    &amp;lt;%= link_to 'Edit', :controller =&amp;gt; 'recipes', :action =&amp;gt; 'edit', :id =&amp;gt; @recipe %&amp;gt; |
&amp;lt;%end%&amp;gt;
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;and add the following to &lt;strong&gt;app/helpers/recipes_helper.rb&lt;/strong&gt;&lt;/p&gt;


&lt;pre&gt;
    &lt;code class=&quot;ruby&quot;&gt;
def is_my_recipe?(recipe, &#38;block)
  yield if recipe.fb_user_id.to_i == @current_fb_user_id.to_i
end
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;See how we cast the facebook user ids to ints. This makes the match actually possible.&lt;/p&gt;


	&lt;p&gt;Now that was easy but it&#8217;s not very Facebooky. Where&#8217;s the social? Lets add some friends stuff.&lt;/p&gt;


	&lt;p&gt;Edit &lt;strong&gt;app/controllers/recipes_controller.rb&lt;/strong&gt; and add the following actions&lt;/p&gt;


&lt;pre&gt;
    &lt;code class=&quot;ruby&quot;&gt;
def my
  @title = &quot;My recipes&quot; 
  @recipes = Recipe.find_my_recipes(@current_fb_user_id)

  render :file =&amp;gt; &quot;recipes/index&quot;, :use_full_path =&amp;gt; true
end

def friends
  @title = &quot;Friends recipes&quot; 

  xml_friends_get = fbsession.friends_get
  friend_ids = xml_friends_get.search(&quot;//uid&quot;).map{|uidNode| uidNode.inner_html.to_i}

  @recipes = Recipe.find_friends_recipes(friend_ids)
  render :file =&amp;gt; &quot;recipes/index&quot;, :use_full_path =&amp;gt; true
end
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;Add the following to your Recipe model at &lt;strong&gt;app/models/recipe.rb&lt;/strong&gt;&lt;/p&gt;


&lt;pre&gt;
    &lt;code class=&quot;ruby&quot;&gt;
class &amp;lt;&amp;lt; self

def find_my_recipes(fb_user_id)
  find(:all, :conditions =&amp;gt; ['fb_user_id = ?', fb_user_id])
end

def find_friends_recipes(friends_fb_ids)
  find(:all, :conditions =&amp;gt; ['fb_user_id IN (?)', friends_fb_ids])
end

end
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;You can see how we use the facebook &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; through the rfacebook &lt;strong&gt;fbsession.friends_get&lt;/strong&gt;. This then returns Hpricot &lt;span class=&quot;caps&quot;&gt;XML&lt;/span&gt; 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.&lt;/p&gt;


	&lt;p&gt;Edit &lt;strong&gt;app/views/layouts/index.rhtml&lt;/strong&gt; and include the following just under the body tag&lt;/p&gt;


&lt;pre&gt;
    &lt;code class=&quot;ruby&quot;&gt;
    &amp;lt;div id=&quot;navigation&quot;&amp;gt;
&amp;lt;%= link_to 'All recipes', :controller=&amp;gt;'recipes'%&amp;gt; | 
&amp;lt;%= link_to 'My recipes', :controller=&amp;gt;'recipes', :action =&amp;gt; 'my'%&amp;gt; | 
&amp;lt;%= link_to 'Friends recipes', :controller=&amp;gt;'recipes', :action =&amp;gt; 'friends'%&amp;gt;
    &amp;lt;/div&amp;gt;
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;We&#8217;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.&lt;/p&gt;


	&lt;p&gt;&lt;img src=&quot;http://www.liverail.net/assets/2007/6/29/Picture_5.png&quot; /&gt;&lt;/p&gt;


	&lt;p&gt;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.&lt;/p&gt;


	&lt;p&gt;&lt;img src=&quot;http://www.liverail.net/assets/2007/6/29/Picture_6.png&quot; /&gt;&lt;/p&gt;


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


	&lt;p&gt;&lt;img src=&quot;http://www.liverail.net/assets/2007/6/29/Picture_8.png&quot; /&gt;&lt;/p&gt;


	&lt;p&gt;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&#8217;y. We shall now go on and look at turning this into a Canvas application. In a canvas &lt;span class=&quot;caps&quot;&gt;FBML&lt;/span&gt; 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 &lt;a href=&quot;http://developers.facebook.com/documentation.php?v=1.0&amp;amp;#38;doc=fbml&quot; title=&quot;FBML&quot;&gt;Facebook Markup Language&lt;/a&gt; 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.&lt;/p&gt;


	&lt;p&gt;Now because Facebook needs to make a request to a server it must be accessible to Facebook, hence you can&#8217;t just run it on your laptop (or you can if you have a static Ip you could route facebook to). But i&#8217;m going to use my excellent &lt;a href=&quot;http://railsmachine.com/&quot;&gt;RailsMachine&lt;/a&gt; serving to deploy the application at http://socialrecipe.liverail.net/. So don&#8217;t attempt these next steps unless you can also deploy your server to the world.&lt;/p&gt;


First of all we need to switch our layouts if we are in the canvas. So change the &lt;strong&gt;app/controllers/application.rb&lt;/strong&gt;
&lt;pre&gt;
    &lt;code class=&quot;ruby&quot;&gt;
layout 'index'
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;to&lt;/p&gt;


&lt;pre&gt;
    &lt;code class=&quot;ruby&quot;&gt;
layout :check_fb_layout

def check_fb_layout
  if in_facebook_canvas?
    &quot;index_fbml&quot; 
  else
    &quot;index&quot; 
  end
end
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;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 &lt;strong&gt;app/views/layouts/index_fbml.rhtml&lt;/strong&gt;&lt;/p&gt;


&lt;pre&gt;
    &lt;code class=&quot;ruby&quot;&gt;
&amp;lt;fb:dashboard&amp;gt;
  &amp;lt;fb:header decoration=&quot;add_border&quot; icon=&quot;false&quot;&amp;gt;Liverail Recipes&amp;lt;/fb:header&amp;gt;
  &amp;lt;fb:create-button 
href=&quot;&amp;lt;%= url_for(:controller =&amp;gt; 'recipes', :action =&amp;gt; &quot;new&quot;, :only_path =&amp;gt; true) %&amp;gt;&quot;&amp;gt;
New Recipe&amp;lt;/fb:create-button&amp;gt;    
&amp;lt;/fb:dashboard&amp;gt;
&amp;lt;fb:tabs&amp;gt;
  &amp;lt;fb:tab_item 
href=&quot;http://apps.facebook.com&amp;lt;%= url_for(:controller =&amp;gt; 'recipes', :action =&amp;gt; &quot;index&quot;, :only_path =&amp;gt; true) %&amp;gt;&quot; 
title=&quot;All Recipes&quot;&amp;gt;&amp;lt;/fb:tab_item&amp;gt;
  &amp;lt;fb:tab_item 
href=&quot;http://apps.facebook.com&amp;lt;%= url_for(:controller =&amp;gt; 'recipes', :action =&amp;gt; &quot;my&quot;, :only_path =&amp;gt; true) %&amp;gt;&quot; 
title=&quot;My Recipes&quot;&amp;gt;My Recipes&amp;lt;/fb:tab_item&amp;gt;
  &amp;lt;fb:tab_item 
href=&quot;http://apps.facebook.com&amp;lt;%= url_for(:controller =&amp;gt; 'recipes', :action =&amp;gt; &quot;friends&quot;, :only_path =&amp;gt; true) %&amp;gt;&quot; 
title=&quot;Friends Recipes&quot;&amp;gt;Friends Recipes&amp;lt;/fb:tab_item&amp;gt;
&amp;lt;/fb:tabs&amp;gt;

&amp;lt;%unless flash[:notice].blank? %&amp;gt;
&amp;lt;fb:status&amp;gt;&amp;lt;%= flash[:notice] %&amp;gt;&amp;lt;/fb:status&amp;gt;
&amp;lt;%end%&amp;gt;

&amp;lt;%= yield  %&amp;gt;
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;This will add a Facebook navigation tabs. Notice how the &lt;em&gt;fb:create-button_&lt;/em&gt; works fine with a relative &lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt; but the &lt;em&gt;fb:tab_item&lt;/em&gt; requires an absolute url with the &lt;strong&gt;http://apps.facebook.com&lt;/strong&gt;, this is one of the many oddities with &lt;span class=&quot;caps&quot;&gt;FBML&lt;/span&gt;. Additionaly we must surround the &lt;em&gt;fb:status&lt;/em&gt; with a check because it won&#8217;t work if you have a blank tag.&lt;/p&gt;


	&lt;p&gt;We now need to render different markup for our pages.&lt;/p&gt;


	&lt;p&gt;Add the following to &lt;strong&gt;app/controllers/application.rb&lt;/strong&gt;&lt;/p&gt;


&lt;pre&gt;
    &lt;code class=&quot;ruby&quot;&gt;
      def render_facebook(template = default_template_name)
        if in_facebook_canvas? #or true
           render :action =&amp;gt; &quot;#{template}_fbml&quot; 
        else
           render :action =&amp;gt; &quot;#{template}&quot; 
        end
      end
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;You now need to add a call to &lt;strong&gt;render_facebook&lt;/strong&gt; at the end of actions &lt;em&gt;index&lt;/em&gt;, &lt;em&gt;show&lt;/em&gt;, &lt;em&gt;new&lt;/em&gt;, &lt;em&gt;edit&lt;/em&gt; for the recipes controller, add a call to &lt;strong&gt;render_facebook &#8220;index&#8221;&lt;/strong&gt; at the end of actions &lt;em&gt;my&lt;/em&gt;, &lt;em&gt;friends&lt;/em&gt; for the recipes controller and finally &lt;strong&gt;render_facebook&lt;/strong&gt; at the end of actions  &lt;em&gt;new&lt;/em&gt; for the comments controller.&lt;/p&gt;


	&lt;p&gt;Lets create some &lt;span class=&quot;caps&quot;&gt;FBML&lt;/span&gt; rendering templates.&lt;/p&gt;


	&lt;p&gt;First &lt;strong&gt;app/views/recipes/index_fbml.rhtml&lt;/strong&gt;&lt;/p&gt;


&lt;pre&gt;
    &lt;code class=&quot;ruby&quot;&gt;
        &amp;lt;fb:header decoration=&quot;add_border&quot; icon=&quot;false&quot;&amp;gt;&amp;lt;%= @title %&amp;gt;&amp;lt;/fb:header&amp;gt;
        &amp;lt;%@recipes.each do |recipe| %&amp;gt;
            &amp;lt;div&amp;gt;
            &amp;lt;h3&amp;gt;&amp;lt;%= link_to h(recipe.title), :controller =&amp;gt; 'recipes', :action =&amp;gt; 'show', :id =&amp;gt; recipe%&amp;gt;&amp;lt;/h3&amp;gt;
            &amp;lt;p&amp;gt;
                      &amp;lt;fb:profile-pic uid=&quot;&amp;lt;%= recipe.fb_user_id %&amp;gt;&quot; size=&quot;thumb&quot; /&amp;gt;
                      &amp;lt;fb:name uid=&quot;&amp;lt;%= recipe.fb_user_id %&amp;gt;&quot; ifcantsee=&quot;anonymous&quot; /&amp;gt;
                       &amp;lt;/p&amp;gt;
            &amp;lt;p&amp;gt;&amp;lt;%=h recipe.summary %&amp;gt;&amp;lt;/p&amp;gt;
            &amp;lt;/div&amp;gt;
        &amp;lt;%end%&amp;gt;
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;&lt;strong&gt;app/views/recipes/new_fbml.rhtml&lt;/strong&gt;&lt;/p&gt;


&lt;pre&gt;
    &lt;code class=&quot;ruby&quot;&gt;
        &amp;lt;fb:header decoration=&quot;add_border&quot; icon=&quot;false&quot;&amp;gt;New Recipe&amp;lt;/fb:header&amp;gt;
        &amp;lt;%unless @recipe.errors.blank?%&amp;gt;
        &amp;lt;fb:error&amp;gt;&amp;lt;%= error_messages_for :recipe %&amp;gt;&amp;lt;/fb:error&amp;gt;
        &amp;lt;%end%&amp;gt;

            &amp;lt;% form_for(:recipe, :url =&amp;gt; {:controller =&amp;gt; 'recipes', :action =&amp;gt; 'create'}) do |f| %&amp;gt;
              &amp;lt;dl&amp;gt;
                  &amp;lt;dt&amp;gt;&amp;lt;label for=&quot;recipe_title&quot;&amp;gt;Title:&amp;lt;/label&amp;gt;&amp;lt;/dt&amp;gt;
                &amp;lt;dd&amp;gt;&amp;lt;%= f.text_field :title %&amp;gt;&amp;lt;/dd&amp;gt;
                &amp;lt;dt&amp;gt;&amp;lt;label for=&quot;recipe_summary&quot;&amp;gt;Summary:&amp;lt;/label&amp;gt;&amp;lt;/dt&amp;gt;
                &amp;lt;dd&amp;gt;&amp;lt;%= f.text_area :summary %&amp;gt;&amp;lt;/dd&amp;gt;
                &amp;lt;dt&amp;gt;&amp;lt;label for=&quot;recipe_ingredients&quot;&amp;gt;Ingredients:&amp;lt;/label&amp;gt;&amp;lt;/dt&amp;gt;
                &amp;lt;dd&amp;gt;&amp;lt;%= f.text_area :ingredients %&amp;gt;&amp;lt;/dd&amp;gt;
                &amp;lt;dt&amp;gt;&amp;lt;label for=&quot;recipe_instructions&quot;&amp;gt;Cooking Instructions:&amp;lt;/label&amp;gt;&amp;lt;/dt&amp;gt;
                &amp;lt;dd&amp;gt;&amp;lt;%= f.text_area :instructions %&amp;gt;&amp;lt;/dd&amp;gt;
                &amp;lt;dt&amp;gt;&amp;lt;label for=&quot;recipe_cooking_time&quot;&amp;gt;Cooking Time:&amp;lt;/label&amp;gt;&amp;lt;/dt&amp;gt;
                &amp;lt;dd&amp;gt;&amp;lt;%= f.text_field :cooking_time %&amp;gt; mins&amp;lt;/dd&amp;gt;
                &amp;lt;dt&amp;gt;&amp;lt;/dt&amp;gt;
                &amp;lt;dd&amp;gt;&amp;lt;%= submit_tag &quot;Create&quot; %&amp;gt;&amp;lt;/dd&amp;gt;
              &amp;lt;/dl&amp;gt;
            &amp;lt;%= f.hidden_field :fb_user_id, :value =&amp;gt; @current_fb_user_id %&amp;gt;
            &amp;lt;% end %&amp;gt;

        &amp;lt;br/&amp;gt;
        &amp;lt;%= link_to 'Back', :controller =&amp;gt; 'recipes' %&amp;gt;
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;&lt;strong&gt;app/views/recipes/edit_fbml.rhtml&lt;/strong&gt;&lt;/p&gt;


&lt;pre&gt;
    &lt;code class=&quot;ruby&quot;&gt;
        &amp;lt;fb:header decoration=&quot;add_border&quot; icon=&quot;false&quot;&amp;gt;Edit Recipe&amp;lt;/fb:header&amp;gt;
        &amp;lt;%unless @recipe.errors.blank?%&amp;gt;
        &amp;lt;fb:error&amp;gt;&amp;lt;%= error_messages_for :recipe %&amp;gt;&amp;lt;/fb:error&amp;gt;
        &amp;lt;%end%&amp;gt;

        &amp;lt;% form_for(:recipe, :url =&amp;gt; {:controller =&amp;gt;'recipes', :action =&amp;gt; 'update', :id =&amp;gt; @recipe}) do |f| %&amp;gt;
        &amp;lt;dl&amp;gt;
            &amp;lt;dt&amp;gt;&amp;lt;label for=&quot;recipe_title&quot;&amp;gt;Title:&amp;lt;/label&amp;gt;&amp;lt;/dt&amp;gt;
            &amp;lt;dd&amp;gt;&amp;lt;%= f.text_field :title %&amp;gt;&amp;lt;/dd&amp;gt;
            &amp;lt;dt&amp;gt;&amp;lt;label for=&quot;recipe_summary&quot;&amp;gt;Summary:&amp;lt;/label&amp;gt;&amp;lt;/dt&amp;gt;
            &amp;lt;dd&amp;gt;&amp;lt;%= f.text_area :summary %&amp;gt;&amp;lt;/dd&amp;gt;
            &amp;lt;dt&amp;gt;&amp;lt;label for=&quot;recipe_ingredients&quot;&amp;gt;Ingredients:&amp;lt;/label&amp;gt;&amp;lt;/dt&amp;gt;
            &amp;lt;dd&amp;gt;&amp;lt;%= f.text_area :ingredients %&amp;gt;&amp;lt;/dd&amp;gt;
            &amp;lt;dt&amp;gt;&amp;lt;label for=&quot;recipe_instructions&quot;&amp;gt;Cooking Instructions:&amp;lt;/label&amp;gt;&amp;lt;/dt&amp;gt;
            &amp;lt;dd&amp;gt;&amp;lt;%= f.text_area :instructions %&amp;gt;&amp;lt;/dd&amp;gt;
            &amp;lt;dt&amp;gt;&amp;lt;label for=&quot;recipe_cooking_time&quot;&amp;gt;Cooking Time:&amp;lt;/label&amp;gt;&amp;lt;/dt&amp;gt;
            &amp;lt;dd&amp;gt;&amp;lt;%= f.text_field :cooking_time %&amp;gt; mins&amp;lt;/dd&amp;gt;
            &amp;lt;dt&amp;gt;&amp;lt;/dt&amp;gt;
            &amp;lt;dd&amp;gt;&amp;lt;%= submit_tag &quot;Update&quot; %&amp;gt;&amp;lt;/dd&amp;gt;
        &amp;lt;/dl&amp;gt;
        &amp;lt;% end %&amp;gt;

        &amp;lt;br/&amp;gt;
        &amp;lt;%= link_to 'Show', :controller =&amp;gt; 'recipes', :action =&amp;gt; 'show', :id =&amp;gt;@recipe %&amp;gt; |
        &amp;lt;%= link_to 'Back', :controller =&amp;gt; 'recipes' %&amp;gt;
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;&lt;strong&gt;app/views/recipes/show_fbml.rhtml&lt;/strong&gt;&lt;/p&gt;


&lt;pre&gt;
    &lt;code class=&quot;ruby&quot;&gt;
&amp;lt;fb:header decoration=&quot;add_border&quot; icon=&quot;false&quot;&amp;gt;
&amp;lt;%=h @recipe.title %&amp;gt;
&amp;lt;/fb:header&amp;gt;
&amp;lt;fb:profile-pic uid=&quot;&amp;lt;%= @recipe.fb_user_id %&amp;gt;&quot; size=&quot;normal&quot; /&amp;gt; 
&amp;lt;fb:name uid=&quot;&amp;lt;%= @recipe.fb_user_id %&amp;gt;&quot; ifcantsee=&quot;anonymous&quot; /&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;%=h @recipe.summary %&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;h2&amp;gt;Ingredients:&amp;lt;/h2&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;%=h @recipe.ingredients %&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;h2&amp;gt;Instructions:&amp;lt;/h2&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;%=h @recipe.instructions %&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;&amp;lt;em&amp;gt;Cooking time is around &amp;lt;%=h @recipe.cooking_time %&amp;gt; mins&amp;lt;/em&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;div id=&quot;comments&quot;&amp;gt;
    &amp;lt;h2&amp;gt;Displaying &amp;lt;%=pluralize(@recipe.comments.size, 'comment')%&amp;gt;&amp;lt;/h2&amp;gt;
    &amp;lt;%= link_to 'New comment', :controller =&amp;gt; 'comments', :action =&amp;gt; 'new', :recipe_id =&amp;gt; @recipe %&amp;gt;
       &amp;lt;% @recipe.comments.each do |comment| %&amp;gt;
           &amp;lt;div&amp;gt;
                &amp;lt;fb:profile-pic uid=&quot;&amp;lt;%= comment.fb_user_id %&amp;gt;&quot; size=&quot;thumb&quot; /&amp;gt;
            &amp;lt;p&amp;gt;&amp;lt;%= comment.body %&amp;gt;&amp;lt;/p&amp;gt;    
                posted &amp;lt;%= time_ago_in_words(comment.created_at)  %&amp;gt; 
ago by 
&amp;lt;strong&amp;gt;
&amp;lt;fb:name uid=&quot;&amp;lt;%= comment.fb_user_id %&amp;gt;&quot; ifcantsee=&quot;anonymous&quot; /&amp;gt;
&amp;lt;/strong&amp;gt;
            &amp;lt;/div&amp;gt;
       &amp;lt;%end %&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;br/&amp;gt;
&amp;lt;%is_my_recipe? @recipe do %&amp;gt;
    &amp;lt;%= link_to 'Edit', :controller =&amp;gt; 'recipes', :action =&amp;gt; 'edit', :id =&amp;gt; @recipe %&amp;gt; |
&amp;lt;%end%&amp;gt;
&amp;lt;%= link_to 'Back', :controller =&amp;gt; 'recipes' %&amp;gt;
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;&lt;strong&gt;app/views/comments/new_fbml.rhtml&lt;/strong&gt;&lt;/p&gt;


&lt;pre&gt;
    &lt;code class=&quot;ruby&quot;&gt;
&amp;lt;fb:header decoration=&quot;add_border&quot; icon=&quot;false&quot;&amp;gt;New Comment&amp;lt;/fb:header&amp;gt;
&amp;lt;%unless @comment.errors.blank?%&amp;gt;
&amp;lt;fb:error&amp;gt;&amp;lt;%= error_messages_for :comment %&amp;gt;&amp;lt;/fb:error&amp;gt;
&amp;lt;%end%&amp;gt;

&amp;lt;% form_for(:comment, :url =&amp;gt; {:controller =&amp;gt; 'comments', :action =&amp;gt; 'create'}) do |f| %&amp;gt;
&amp;lt;dl&amp;gt;
    &amp;lt;dt&amp;gt;&amp;lt;label for=&quot;comment_body&quot;&amp;gt;Body Content:&amp;lt;/label&amp;gt;&amp;lt;/dt&amp;gt;
    &amp;lt;dd&amp;gt;&amp;lt;%= f.text_area :body %&amp;gt;&amp;lt;/dd&amp;gt;
    &amp;lt;dt&amp;gt;&amp;lt;/dt&amp;gt;
    &amp;lt;dd&amp;gt;&amp;lt;%= submit_tag &quot;Create&quot; %&amp;gt;&amp;lt;/dd&amp;gt;
&amp;lt;/dl&amp;gt;
    &amp;lt;%= f.hidden_field :recipe_id, :value =&amp;gt; @comment.recipe_id %&amp;gt;
    &amp;lt;%= f.hidden_field :fb_user_id, :value =&amp;gt; @current_fb_user_id %&amp;gt;
&amp;lt;% end %&amp;gt;

&amp;lt;br/&amp;gt;
&amp;lt;%= link_to 'Back', :controller =&amp;gt; 'recipes', :action =&amp;gt; 'show', :id =&amp;gt; @comment.recipe_id %&amp;gt;
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;Now i&#8217;m all done. I&#8217;m deploying my application to socialrecipe.liverail.net using capistrano and their great &lt;a href=&quot;https://support.railsmachine.com/index.php?pg=kb.page&amp;amp;#38;id=12&quot;&gt;5 min app deployment&lt;/a&gt; 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 &amp;gt; See my apps &amp;gt; Edit Settings. Now change the Callback &lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt; from &lt;strong&gt;http://localhost:3000/socialrecipe/&lt;/strong&gt; to &lt;strong&gt;http://socialrecipe.liverail.net/socialrecipe/&lt;/strong&gt; with your own names of course. Now click the Use &lt;span class=&quot;caps&quot;&gt;FBML&lt;/span&gt; radio button and save&lt;/p&gt;


	&lt;p&gt;Go to http://apps.facebook.com/socialrecipe. Done! Ruby on Rails Facebook application.&lt;/p&gt;


	&lt;p&gt;&lt;img src=&quot;http://www.liverail.net/assets/2007/6/29/Picture_9.png&quot; /&gt;&lt;/p&gt;


	&lt;p&gt;It isn&#8217;t the best looking but you can style to your heart&#8217;s content. Go to &lt;a href=&quot;http://www.facebook.com/apps/application.php?id=2546581267&quot;&gt;here&lt;/a&gt; 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.&lt;/p&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;UPDATE&lt;/span&gt;: The second part can be found &lt;a href=&quot;http://www.liverail.net/articles/2007/7/16/continuing-facebook-applications-with-ruby-on-rails&quot;&gt;here&lt;/a&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.liverail.net/">
    <author>
      <name>stuarteccles</name>
    </author>
    <id>tag:www.liverail.net,2007-06-24:1867</id>
    <published>2007-06-24T10:23:00Z</published>
    <updated>2007-06-24T10:48:10Z</updated>
    <category term="Enterprise2.0"/>
    <category term="mashups enterprise2.0"/>
    <link href="http://www.liverail.net/articles/2007/6/24/broadening-the-enterprise-2-0-remit-with-mashups" rel="alternate" type="text/html"/>
    <title>Broadening the Enterprise 2.0 remit with mashups</title>
<content type="html">
            &lt;p&gt;InfoQ has a great presentation &lt;a href=&quot;http://www.infoq.com/presentations/enterprise-mashups&quot;&gt;Mash-ups Meet the Enterprise&lt;/a&gt; by Rodney Smith at &lt;span class=&quot;caps&quot;&gt;IBM&lt;/span&gt; discussing the application of web2.0 technologies within the corporate firewall. This is nothing new and has been an explosive topic since my post in February 2006 &lt;a href=&quot;http://www.liverail.net/enterprise2-0&quot;&gt;Enterprise 2.0&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;What is interesting are the areas beyond the typical talk of Enterprise blogs and Wikis and taking about the &#8220;personal mash-up&#8221; which relates to my first and second points of Enterprise 2.0&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;Delivering all off the company information as addressable discoverable sources.&lt;/li&gt;
		&lt;li&gt;Allow custom mash-ups of this information on a user-by-user basis&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;It&#8217;s the second point which Rodney Smtih is talking about. The ability for all users in the Enterprise to create their own mash-ups of corporate and web data and deliver the information they need independent of a companies IT departments. A so called &#8220;do-it-yourself&#8221; IT or Enterprise Mash-up.&lt;/p&gt;


	&lt;p&gt;Rodney Smith also talks about making your corporate information &#8220;mashable&#8221; which relates to my first point of addressable discoverable sources.&lt;/p&gt;


	&lt;p&gt;I think software like this is appearing on the larger web and will move swiftly into the Enterprise. Sites such as &lt;a href=&quot;http://pipes.yahoo.com/pipes/&quot;&gt;Yahoo pipes&lt;/a&gt; and &lt;a href=&quot;http://www.ning.com/&quot;&gt;Ning&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;The problem with these kinds of &lt;em&gt;user created applications&lt;/em&gt; is the likely backlash from corporate IT departments who are used to gate-keeping this kind of development. Instead IT needs to focus on the problems which need to be solved to create this kind of environment. This would include middleware and identity services.&lt;/p&gt;


	&lt;p&gt;So does this fall-in &lt;a href=&quot;http://blog.hbs.edu/faculty/amcafee/&quot;&gt;Andrew McAfee&#8217;s&lt;/a&gt; definition of Enterprise 2.0?&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;&#8220;Enterprise 2.0 is the use of emergent social software platforms within companies, or between companies and their partners or customers.&#8221;&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;The answer. Absolutely. Social software platforms is not limited to blogs, wiki&#8217;s and friends networks but a few more ranging remit. I like McAfee&#8217;s definition, it doesn&#8217;t try to be all inclusive but does focus the term more clearly than the scatter-gun that is web 2.0. The &lt;em&gt;personal mashup&lt;/em&gt; will be the use of a social software platform.&lt;/p&gt;
          </content>  </entry>
</feed>
