<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <title>All about Rails - Home</title>
  <id>tag:blog.viarails.net,2008:mephisto/</id>
  <generator uri="http://mephistoblog.com" version="0.7.3">Mephisto Noh-Varr</generator>
  <link href="http://blog.viarails.net/feed/atom.xml" rel="self" type="application/atom+xml"/>
  <link href="http://blog.viarails.net/" rel="alternate" type="text/html"/>
  <updated>2008-05-21T16:41:08Z</updated>
  <entry xml:base="http://blog.viarails.net/">
    <author>
      <name>Wesley</name>
    </author>
    <id>tag:blog.viarails.net,2008-05-21:37</id>
    <published>2008-05-21T16:38:00Z</published>
    <updated>2008-05-21T16:41:08Z</updated>
    <category term="rails session store"/>
    <link href="http://blog.viarails.net/2008/5/21/session-store-switching" rel="alternate" type="text/html"/>
    <title>Session Store Switching</title>
<content type="html">
            &lt;p&gt;I wrote a short article about a little gotcha, and the solution to it when switching your rails session store. Check it out: &lt;a href='http://rails.learnhub.com/lesson/page/1858-how-to-switch-your-default-session-store'&gt;http://rails.learnhub.com/lesson/page/1858-how-to-switch-your-default-session-store&lt;/a&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://blog.viarails.net/">
    <author>
      <name>Wesley</name>
    </author>
    <id>tag:blog.viarails.net,2008-04-04:35</id>
    <published>2008-04-04T02:50:00Z</published>
    <updated>2008-04-04T02:59:04Z</updated>
    <category term="git"/>
    <link href="http://blog.viarails.net/2008/4/4/how-to-convert-your-svn-repo-to-git" rel="alternate" type="text/html"/>
    <title>How to convert your svn repo to git</title>
<content type="html">
            &lt;p&gt;
Everyone loves git (unless you love mecurial), and svn is so passe, so it's time to hop on the bandwagon!
&lt;/p&gt;

&lt;b&gt;Step 1&lt;/b&gt;: Install Git. I use macports. 

&lt;pre&gt;&lt;code&gt;
# sudo port install git-core +svn
&lt;/code&gt;&lt;/pre&gt;

Others may want to use one of these commands:

&lt;pre&gt;&lt;code&gt;
# sudo apt-get install git-core
# yum install git-core
# emerge -av git
# sudo pkg_add -i git-svn  
# sudo pkg_add -r git
&lt;/code&gt;&lt;/pre&gt;

&lt;b&gt;Step 2&lt;/b&gt;: Check out your svn project with git. This may take a while, my project took about 20 minutes and it has 1300+ commits.

&lt;pre&gt;&lt;code&gt;
# git-svn clone https://svn.yourhost.name/projectname projectname.git
&lt;/code&gt;&lt;/pre&gt;

&lt;b&gt;Step 3&lt;/b&gt;: Get any commits that may have been made to your subversion repo while you were exporting it.

&lt;pre&gt;&lt;code&gt;
# git-svn rebase
&lt;/code&gt;&lt;/pre&gt;

Now you've got a functional git clone of your subversion repo. git commands are very similar to svn commands. For example:

&lt;pre&gt;&lt;code&gt;
# git commit -a -m &quot;This is a commit message&quot;
# git help  (to learn about more commands)
&lt;/code&gt;&lt;/pre&gt;

If you want to commit the changes you have made to your git repo to your svn repo, it's quite easy:

&lt;pre&gt;&lt;code&gt;
# git-svn dcommit
&lt;/code&gt;&lt;/pre&gt;
          </content>  </entry>
  <entry xml:base="http://blog.viarails.net/">
    <author>
      <name>Wesley</name>
    </author>
    <id>tag:blog.viarails.net,2008-04-03:34</id>
    <published>2008-04-03T15:52:00Z</published>
    <updated>2008-04-04T12:41:51Z</updated>
    <category term="rails"/>
    <link href="http://blog.viarails.net/2008/4/3/proper-use-of-partials" rel="alternate" type="text/html"/>
    <title>Calling partials through helpers</title>
<content type="html">
            &lt;p&gt;
&lt;a href='http://wiki.rubyonrails.org/rails/pages/Partials'&gt;Rails partials&lt;/a&gt; are are fragments of template code that can be inserted into a view. They can really simplify template code, by factoring out repeated code.
&lt;/p&gt;
&lt;p&gt;
For example, I often put forms into a partial so that the form can be shared be create and edit views:
&lt;/p&gt;
&lt;div&gt;
quizzes/new.html.haml
&lt;table class='CodeRay'&gt;&lt;tr&gt;
  &lt;td title='click to toggle' class='line_numbers'&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class='code'&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;= error_messages_for :quiz&lt;tt&gt;
&lt;/tt&gt;- form_for :quiz, @quiz, :url =&lt;span class='er'&gt;&amp;gt;&lt;/span&gt; quizzes_path, :html =&lt;span class='er'&gt;&amp;gt;&lt;/span&gt; {:method =&lt;span class='er'&gt;&amp;gt;&lt;/span&gt; :post} do |form|&lt;tt&gt;
&lt;/tt&gt;  = render :partial =&lt;span class='er'&gt;&amp;gt;&lt;/span&gt; 'quizzes/form', :locals =&lt;span class='er'&gt;&amp;gt;&lt;/span&gt; {:form =&lt;span class='er'&gt;&amp;gt;&lt;/span&gt; form}&lt;tt&gt;
&lt;/tt&gt;  = submit_tag 'Create'&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;/div&gt;
&lt;div&gt;
quizzes/edit.html.haml
&lt;table class='CodeRay'&gt;&lt;tr&gt;
  &lt;td title='click to toggle' class='line_numbers'&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class='code'&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;= error_messages_for :quiz&lt;tt&gt;
&lt;/tt&gt;- form_for :quiz, @quiz, :url =&lt;span class='er'&gt;&amp;gt;&lt;/span&gt; quiz_path(@quiz), :html =&lt;span class='er'&gt;&amp;gt;&lt;/span&gt; {:method =&lt;span class='er'&gt;&amp;gt;&lt;/span&gt; :put} do |form|&lt;tt&gt;
&lt;/tt&gt;  = render :partial =&lt;span class='er'&gt;&amp;gt;&lt;/span&gt; 'quizzes/form', :locals =&lt;span class='er'&gt;&amp;gt;&lt;/span&gt; {:form =&lt;span class='er'&gt;&amp;gt;&lt;/span&gt; form}&lt;tt&gt;
&lt;/tt&gt;  = submit_tag 'Update'&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;/div&gt;
&lt;p&gt;
Many (most) people put the render call directly in their templates. This is not a good idea! What if you want to change the template path, or conditionally render a different template in certain conditions? Now you've got to repeat yourself in both templates, and that's bad news.
&lt;/p&gt;
&lt;p&gt;
A simple way to fix this is to *always* use a helper to render the partial. That way any changes can be made in one place, and it also a great place to store any messy conditional logic so that it doesn't clutter up your templates.
&lt;/p&gt;
&lt;div&gt;
quizzes/new.html.haml
&lt;table class='CodeRay'&gt;&lt;tr&gt;
  &lt;td title='click to toggle' class='line_numbers'&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class='code'&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;= error_messages_for :quiz&lt;tt&gt;
&lt;/tt&gt;- form_for :quiz, @quiz, :url =&lt;span class='er'&gt;&amp;gt;&lt;/span&gt; quizzes_path, :html =&lt;span class='er'&gt;&amp;gt;&lt;/span&gt; {:method =&lt;span class='er'&gt;&amp;gt;&lt;/span&gt; :post} do |form|&lt;tt&gt;
&lt;/tt&gt;  = quiz_form(form)&lt;tt&gt;
&lt;/tt&gt;  = submit_tag 'Create'&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;/div&gt;
&lt;div&gt;
quizzes/edit.html.haml
&lt;table class='CodeRay'&gt;&lt;tr&gt;
  &lt;td title='click to toggle' class='line_numbers'&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class='code'&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;= error_messages_for :quiz&lt;tt&gt;
&lt;/tt&gt;- form_for :quiz, @quiz, :url =&lt;span class='er'&gt;&amp;gt;&lt;/span&gt; quiz_path(@quiz), :html =&lt;span class='er'&gt;&amp;gt;&lt;/span&gt; {:method =&lt;span class='er'&gt;&amp;gt;&lt;/span&gt; :put} do |form|&lt;tt&gt;
&lt;/tt&gt;  = quiz_form(form)&lt;tt&gt;
&lt;/tt&gt;  = submit_tag 'Update'&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;/div&gt;
&lt;div&gt;
quizzes_helper.rb
&lt;table class='CodeRay'&gt;&lt;tr&gt;
  &lt;td title='click to toggle' class='line_numbers'&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class='code'&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;def quiz_form(form)&lt;tt&gt;
&lt;/tt&gt;   render :partial =&lt;span class='er'&gt;&amp;gt;&lt;/span&gt; 'quizzes/form', :locals =&lt;span class='er'&gt;&amp;gt;&lt;/span&gt; {:form =&lt;span class='er'&gt;&amp;gt;&lt;/span&gt; form}&lt;tt&gt;
&lt;/tt&gt;end&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;/div&gt;
&lt;p&gt;
Now if I want to do something, like say render a different form depending on a user's preference, it's easy to do.
&lt;/p&gt;
&lt;div&gt;
quizzes/new.html.haml
&lt;table class='CodeRay'&gt;&lt;tr&gt;
  &lt;td title='click to toggle' class='line_numbers'&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class='code'&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;= error_messages_for :quiz&lt;tt&gt;
&lt;/tt&gt;- form_for :quiz, @quiz, :url =&lt;span class='er'&gt;&amp;gt;&lt;/span&gt; quizzes_path, :html =&lt;span class='er'&gt;&amp;gt;&lt;/span&gt; {:method =&lt;span class='er'&gt;&amp;gt;&lt;/span&gt; :post} do |form|&lt;tt&gt;
&lt;/tt&gt;  = quiz_form(form, current_user)&lt;tt&gt;
&lt;/tt&gt;  = submit_tag 'Create'&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;/div&gt;

&lt;div&gt;
quizzes_helper.rb
&lt;table class='CodeRay'&gt;&lt;tr&gt;
  &lt;td title='click to toggle' class='line_numbers'&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class='code'&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;def quiz_form(form, user = nil)&lt;tt&gt;
&lt;/tt&gt;   if(!user.nil? &lt;span class='er'&gt;&amp;amp;&lt;/span&gt;&lt;span class='er'&gt;&amp;amp;&lt;/span&gt; user.wants_advanced_quizzes))&lt;tt&gt;
&lt;/tt&gt;     render :partial =&lt;span class='er'&gt;&amp;gt;&lt;/span&gt; 'quizzes/advanced_form', :locals =&lt;span class='er'&gt;&amp;gt;&lt;/span&gt; {:form =&lt;span class='er'&gt;&amp;gt;&lt;/span&gt; form}&lt;tt&gt;
&lt;/tt&gt;   else&lt;tt&gt;
&lt;/tt&gt;     render :partial =&lt;span class='er'&gt;&amp;gt;&lt;/span&gt; 'quizzes/form', :locals =&lt;span class='er'&gt;&amp;gt;&lt;/span&gt; {:form =&lt;span class='er'&gt;&amp;gt;&lt;/span&gt; form}&lt;tt&gt;
&lt;/tt&gt;   end&lt;tt&gt;
&lt;/tt&gt;end&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;/div&gt;
          </content>  </entry>
  <entry xml:base="http://blog.viarails.net/">
    <author>
      <name>Wesley</name>
    </author>
    <id>tag:blog.viarails.net,2008-03-06:32</id>
    <published>2008-03-06T03:36:00Z</published>
    <updated>2008-04-03T16:02:17Z</updated>
    <link href="http://blog.viarails.net/2008/3/6/ie8-beta-is-out" rel="alternate" type="text/html"/>
    <title>IE8 beta is out</title>
<content type="html">
            &lt;p&gt;A &lt;a href='http://www.osnews.com/comments/19068'&gt;lot&lt;/a&gt; of &lt;a href='http://channel9.msdn.com/ShowPost.aspx?PostID=367214'&gt;people&lt;/a&gt; were &lt;a href='http://www.neowin.net/forum/index.php?s=6d8ea05ba562b1cffaef3b596cd4d5a4&amp;amp;amp;showtopic=623489&amp;amp;amp;pid=589250460&amp;amp;amp;st=15&amp;amp;amp;#entry589250460'&gt;really optimistic&lt;/a&gt; when it was &lt;a href='http://blogs.msdn.com/ie/archive/2007/12/19/internet-explorer-8-and-acid2-a-milestone.aspx'&gt;announced that IE 8 would render Acid2&lt;/a&gt;, something that Firefox2 can't even do (Firefox beta3 can however).&lt;/p&gt; 

&lt;p&gt;It was thought that Microsoft was finally catching up in terms of standards compliance with the other popular browsers. To bad that rendering Acid2 doesn't really mean that the browser is 'standards compliant'. It just means that it can render the subset of the standard that Acid2 tests. With the release of Acid3, it looks like Microsoft focused solely on rendering Acid2, not on the standards in general. IE8 scored a poor 17/100 on Acid3. 
&lt;/p&gt;
&lt;div&gt;
&lt;a href='http://blog.viarails.net/assets/2008/3/6/ie8-acid3.png'&gt;
&lt;img src='http://blog.viarails.net/assets/2008/3/6/ie8-acid3-small.png' alt='Webkit Acid3 result' /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;p&gt;
On the opposite end of the spectrum, Apple's latest Webkit beta scored 86/100.
&lt;/p&gt;
&lt;div&gt;
&lt;a href='http://blog.viarails.net/assets/2008/3/6/safari-webkit.png'&gt;
&lt;img src='http://blog.viarails.net/assets/2008/3/6/acid3-webkit-small.png' alt='Webkit Acid3 result' /&gt;
&lt;/a&gt;
&lt;/div&gt;
          </content>  </entry>
  <entry xml:base="http://blog.viarails.net/">
    <author>
      <name>Wesley</name>
    </author>
    <id>tag:blog.viarails.net,2008-03-04:31</id>
    <published>2008-03-04T17:35:00Z</published>
    <updated>2008-03-05T18:00:30Z</updated>
    <link href="http://blog.viarails.net/2008/3/4/learnhub-launches" rel="alternate" type="text/html"/>
    <title>Learnhub launches!</title>
<content type="html">
            The entire &lt;a href='http://savvica.com'&gt;Savvica&lt;/a&gt; team has been busy since November building &lt;a href='learnhub.com'&gt;Learnhub&lt;/a&gt;, which we launched today at noon. We've had a great time building it, and have a ton of ideas for future features. Check it out!

&lt;div&gt;
&lt;a href='http://blog.viarails.net/assets/2008/3/4/learnhub.png'&gt;&lt;img src='http://blog.viarails.net/assets/2008/3/4/learnhub-small.png' alt='Learnhub Screenshot' /&gt;&lt;/a&gt;
&lt;/div&gt;
          </content>  </entry>
  <entry xml:base="http://blog.viarails.net/">
    <author>
      <name>Wesley</name>
    </author>
    <id>tag:blog.viarails.net,2008-02-27:29</id>
    <published>2008-02-27T23:23:00Z</published>
    <updated>2008-02-27T23:24:20Z</updated>
    <category term="rails gotcha"/>
    <link href="http://blog.viarails.net/2008/2/27/a-gotcha" rel="alternate" type="text/html"/>
    <title>A gotcha</title>
<content type="html">
            &lt;p&gt;
Just got bitten by this. Observers are not called when deleting an object via a through collection.
&lt;/p&gt;
&lt;div&gt;
An example:
&lt;table class='CodeRay'&gt;&lt;tr&gt;
  &lt;td title='click to toggle' class='line_numbers'&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class='code'&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;class Newsletter &lt;span class='er'&gt;&amp;lt;&lt;/span&gt; ActiveRecord::Base&lt;tt&gt;
&lt;/tt&gt;  has_many :subscribers&lt;tt&gt;
&lt;/tt&gt;  has_many :users, :through =&lt;span class='er'&gt;&amp;gt;&lt;/span&gt; :subscribers&lt;tt&gt;
&lt;/tt&gt;end&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;class SubscriberObserver &lt;span class='er'&gt;&amp;lt;&lt;/span&gt;  ActiveRecord::Observer&lt;tt&gt;
&lt;/tt&gt;  def after_destroy(subscriber)&lt;tt&gt;
&lt;/tt&gt;    # do somethng&lt;tt&gt;
&lt;/tt&gt;  end&lt;tt&gt;
&lt;/tt&gt;end&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;# case 1&lt;tt&gt;
&lt;/tt&gt;# deletes a subscriber object. after_destroy is not called&lt;tt&gt;
&lt;/tt&gt;@newsletter.users.delete(user) &lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;# case 2&lt;tt&gt;
&lt;/tt&gt; # after_destroy is called.&lt;tt&gt;
&lt;/tt&gt;subscriber = @newsletter.subscribers.find(:first, :conditions =&lt;span class='er'&gt;&amp;gt;&lt;/span&gt; [&amp;quot;user_id = ?&amp;quot;, user.id])&lt;tt&gt;
&lt;/tt&gt;subscriber.destroy unless subscriber.nil?  &lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;/div&gt;

&lt;p&gt;
In both cases a subscriber object is being destroyed, but the observer is being called only in the second scenario. I'll have to look into patching this when I get a chance ....
&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://blog.viarails.net/">
    <author>
      <name>Wesley</name>
    </author>
    <id>tag:blog.viarails.net,2008-02-26:21</id>
    <published>2008-02-26T21:08:00Z</published>
    <updated>2008-02-26T21:08:05Z</updated>
    <category term="rails annoyances"/>
    <link href="http://blog.viarails.net/2008/2/26/one-thing-i-hate-about-rails" rel="alternate" type="text/html"/>
    <title>One thing I hate about Rails ...</title>
<content type="html">
            &lt;p&gt;
One thing I truly hate in Rails is ActionMailer. It &lt;b&gt;sucks&lt;/b&gt;.
&lt;/p&gt;
&lt;p&gt;
First off (admittedly a minor point), mailers are stored in app/models, even though they are basically a pseudo controllers, complete with view templates (stored in app/views). It makes no sense. 
&lt;/p&gt;
&lt;p&gt;
Secondly, ActionMailer does not have access to named routes or any view helpers.  The 'rails way' would be to call the mailer from a controller, passing the URL as an argument which is just stupid in my opinion. Most of the time I send an email in an application it is due to a change in an model's state, not due to a specific controller interaction. A nice way of doing this through use of active record observers (which also don't have access to routes). 
&lt;/p&gt;
&lt;p&gt;
This means I generally end up hardcoding the URLs in the mailer. It wouldn't be a huge deal if my test coverage checks that the hardcoded url in the email body matches a generated one. But to do that you'll need to write integration tests rather than the default 'ActionMailer' tests that are auto generated. The whole mess frustrates me unlike anything else in Rails.
&lt;/p&gt;
&lt;p&gt;
Merb seems to get it right with its Merb::MailController. Perhaps something similar could be added to Rails via a plugin? 
&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://blog.viarails.net/">
    <author>
      <name>Wesley</name>
    </author>
    <id>tag:blog.viarails.net,2007-11-14:18</id>
    <published>2007-11-14T15:04:00Z</published>
    <updated>2008-02-26T21:13:52Z</updated>
    <category term="rails plugin"/>
    <link href="http://blog.viarails.net/2007/11/14/immutable-attribute-plugin" rel="alternate" type="text/html"/>
    <title>Immutable Attribute Plugin</title>
<content type="html">
            A new Ruby on Rails validation plugin that allows you to mark model attributes as immutable.

Rails surprisingly does not include a validation method to make a model attribute immutable. (That is, the attribute can not be changed after it is set the first time.) I created this validation plugin to help that.

Check out my post on the &lt;a href='http://rails.savvica.com'&gt;Savvica blog&lt;/a&gt;.
          </content>  </entry>
  <entry xml:base="http://blog.viarails.net/">
    <author>
      <name>Wesley</name>
    </author>
    <id>tag:blog.viarails.net,2007-11-03:17</id>
    <published>2007-11-03T22:17:00Z</published>
    <updated>2007-11-03T22:18:07Z</updated>
    <link href="http://blog.viarails.net/2007/11/3/updates-and-such" rel="alternate" type="text/html"/>
    <title>Updates and such ...</title>
<content type="html">
            I resigned my position with TSOT a few weeks ago, and have joined &lt;a href='http://married-inc.com'&gt;John and Malgosia&lt;/a&gt; at &lt;a href='http://savvica.com'&gt;Savvica&lt;/a&gt;. We're going to be building some pretty cool stuff! 
&lt;p&gt;
Last week &lt;a href='http://heycarsten.com'&gt;Carsten&lt;/a&gt; and I were able to knock off a beta of &lt;a href='http://languify.com'&gt;Languify&lt;/a&gt;, which is a tool to help software developers to collect and manage language translations for software localization. It's pretty simple for now, but we've got a lot of cool ideas that we'll be implementing in the near future. Keep an eye on it!
&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://blog.viarails.net/">
    <author>
      <name>Wesley</name>
    </author>
    <id>tag:blog.viarails.net,2007-08-11:15</id>
    <published>2007-08-11T19:00:00Z</published>
    <updated>2007-09-24T17:17:56Z</updated>
    <category term="facebook webapps"/>
    <link href="http://blog.viarails.net/2007/8/11/facebook-developer-garage-updates" rel="alternate" type="text/html"/>
    <title>Facebook Developer Garage Updates</title>
<content type="html">
            &lt;ul&gt;
  &lt;li&gt;
    CityTV &lt;a href='http://www.citynews.ca/international/day/8-8-2007_955.aspx'&gt;did a segment&lt;/a&gt; about the event
  &lt;/li&gt; 
  &lt;li&gt;
    &lt;a href='http://www.saila.com/'&gt;Craig Saila&lt;/a&gt; posted his &lt;a href='http://www.slideshare.net/csmillie/facebook-profile-updates'&gt;slides about profile updates&lt;/a&gt; and about &lt;a href='http://www.slideshare.net/csaila/fql-overview'&gt;FLQ&lt;/a&gt;
  &lt;/li&gt;
  &lt;li&gt;
    Global Nerdy's &lt;a href='http://globalnerdy.com/2007/08/08/notes-from-facebookcamp-part-1/'&gt; notes &lt;/a&gt;
  &lt;/li&gt;
&lt;/ul&gt;
          </content>  </entry>
  <entry xml:base="http://blog.viarails.net/">
    <author>
      <name>Wesley</name>
    </author>
    <id>tag:blog.viarails.net,2007-08-10:14</id>
    <published>2007-08-10T13:32:00Z</published>
    <updated>2007-08-09T18:32:55Z</updated>
    <category term="openbsd rails"/>
    <link href="http://blog.viarails.net/2007/8/10/rails-on-openbsd" rel="alternate" type="text/html"/>
    <title>Rails on OpenBSD</title>
<content type="html">
            It's extremely easy. 
&lt;ol&gt;
  &lt;li&gt;Install your favorite database server. My favorite is Postgres. 
     &lt;table class='CodeRay'&gt;&lt;tr&gt;
  &lt;td title='click to toggle' class='line_numbers'&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class='code'&gt;&lt;pre&gt;$ sudo pkg_add -i postgresql-server&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

   &lt;/li&gt;
  &lt;li&gt;Install the ruby database bindings for your favorite database server. &lt;table class='CodeRay'&gt;&lt;tr&gt;
  &lt;td title='click to toggle' class='line_numbers'&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class='code'&gt;&lt;pre&gt;$ sudo pkg_add -i ruby-postgres&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/li&gt;
  &lt;li&gt;Install rails. &lt;table class='CodeRay'&gt;&lt;tr&gt;
  &lt;td title='click to toggle' class='line_numbers'&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class='code'&gt;&lt;pre&gt;$ sudo pkg_add -i ruby-rails&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/li&gt;
&lt;/ol&gt;
 That's it!. pkg_add is a great tool (much like apt on debian systems) that takes care of all of the package dependancies.
          </content>  </entry>
  <entry xml:base="http://blog.viarails.net/">
    <author>
      <name>Wesley</name>
    </author>
    <id>tag:blog.viarails.net,2007-08-09:3</id>
    <published>2007-08-09T13:00:00Z</published>
    <updated>2008-02-26T21:15:01Z</updated>
    <category term="rails"/>
    <link href="http://blog.viarails.net/2007/8/9/haml-sass" rel="alternate" type="text/html"/>
    <title>haml &amp; sass</title>
<content type="html">
            &lt;a href='http://haml.hamptoncatlin.com/'&gt;haml&lt;/a&gt; is  template languages for &lt;a href='http://rubyonrails.org'&gt;Ruby on Rails&lt;/a&gt;. It's a plugin that provides an alternative to Rails' native view templating library &lt;a href='http://www.ruby-doc.org/stdlib/libdoc/erb/rdoc/'&gt;erb&lt;/a&gt;. &lt;a href='http://haml.hamptoncatlin.com/docs/sass'&gt;sass&lt;/a&gt; is included with haml, and provides templating for css files. Through clever usage of whitespace, both remove much of the verbosity of html and css (&amp;lt;&amp;gt;, end tags ,etc) , providing a concise  way of creating templates.

For example, take this typical layout template:

&lt;table class='CodeRay'&gt;&lt;tr&gt;
  &lt;td title='click to toggle' class='line_numbers'&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class='code'&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class='pp'&gt;&amp;lt;!DOCTYPE html PUBLIC &amp;quot;-//W3C//DTD XHTML 1.0 Transitional//EN&amp;quot;&lt;tt&gt;
&lt;/tt&gt;       &amp;quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&amp;quot;&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class='ta'&gt;&amp;lt;html&lt;/span&gt; &lt;span class='an'&gt;xmlns&lt;/span&gt;=&lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='k'&gt;http://www.w3.org/1999/xhtml&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class='an'&gt;xml:lang&lt;/span&gt;=&lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='k'&gt;en&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class='an'&gt;lang&lt;/span&gt;=&lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='k'&gt;en&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class='ta'&gt;&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class='ta'&gt;&amp;lt;head&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class='ta'&gt;&amp;lt;meta&lt;/span&gt; &lt;span class='an'&gt;http-equiv&lt;/span&gt;=&lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='k'&gt;content-type&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class='an'&gt;content&lt;/span&gt;=&lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='k'&gt;text/html;charset=UTF-8&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class='ta'&gt;/&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class='ta'&gt;&amp;lt;title&amp;gt;&lt;/span&gt;&lt;span class='c'&gt;&amp;lt;%= controller.action_name %&amp;gt;&lt;/span&gt;&lt;span class='ta'&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class='c'&gt;&amp;lt;%= stylesheet_link_tag 'mycss' %&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class='ta'&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class='ta'&gt;&amp;lt;body&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class='ta'&gt;&amp;lt;p&lt;/span&gt; &lt;span class='an'&gt;style&lt;/span&gt;=&lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='k'&gt;color: green&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class='ta'&gt;&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class='c'&gt;&amp;lt;%= flash[:notice] %&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class='ta'&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class='ta'&gt;&amp;lt;div&lt;/span&gt; &lt;span class='an'&gt;id&lt;/span&gt;=&lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='k'&gt;header&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class='ta'&gt;&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;     &lt;span class='ta'&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Header&lt;span class='ta'&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class='ta'&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class='ta'&gt;&amp;lt;div&lt;/span&gt; &lt;span class='an'&gt;id&lt;/span&gt;=&lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='k'&gt;content&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class='ta'&gt;&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class='c'&gt;&amp;lt;%= yield  %&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class='ta'&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class='ta'&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class='ta'&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


Here's the same thing in haml. Notice the usage of whitespace to delimit block the nesting of the code. Also, regular html can be mixed in as well.

&lt;table class='CodeRay'&gt;&lt;tr&gt;
  &lt;td title='click to toggle' class='line_numbers'&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class='code'&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;!!!&lt;tt&gt;
&lt;/tt&gt;%html{:xmlns =&lt;span class='er'&gt;&amp;gt;&lt;/span&gt; &amp;quot;http://www.w3.org/1999/xhtml&amp;quot;, &amp;quot;xml:lang&amp;quot; =&lt;span class='er'&gt;&amp;gt;&lt;/span&gt; &amp;quot;en&amp;quot;, :lang =&lt;span class='er'&gt;&amp;gt;&lt;/span&gt; &amp;quot;en&amp;quot;}&lt;tt&gt;
&lt;/tt&gt;  %head&lt;tt&gt;
&lt;/tt&gt;    &lt;span class='ta'&gt;&amp;lt;meta&lt;/span&gt; &lt;span class='an'&gt;http-equiv&lt;/span&gt;=&lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='k'&gt;content-type&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class='an'&gt;content&lt;/span&gt;=&lt;span class='s'&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;span class='k'&gt;text/html;charset=UTF-8&lt;/span&gt;&lt;span class='dl'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class='ta'&gt;/&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    %title= controller.action_name&lt;tt&gt;
&lt;/tt&gt;    = stylesheet_link_tag 'mycss'&lt;tt&gt;
&lt;/tt&gt;  %body&lt;tt&gt;
&lt;/tt&gt;    %p{:style =&lt;span class='er'&gt;&amp;gt;&lt;/span&gt; &amp;quot;color:green&amp;quot;}= flash[:notice]&lt;tt&gt;
&lt;/tt&gt;    #header&lt;tt&gt;
&lt;/tt&gt;      %h1 Header&lt;tt&gt;
&lt;/tt&gt;    #content&lt;tt&gt;
&lt;/tt&gt;      = yield&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


There are a few benefits to this:
&lt;ul&gt;
  &lt;li&gt;the information density is greater, so more of the template is visible on screen.&lt;/li&gt;
  &lt;li&gt;less characters to type, so less chance to make a typo&lt;/li&gt;
  &lt;li&gt;nesting is clearly visible, and no more issues with missing end tags.&lt;/li&gt;
&lt;/ul&gt;

sass is similar to haml in that it uses whitespace for nesting, eliminating verbosity. In my next article, I'll explain the benefits and usage of Sass.
          </content>  </entry>
  <entry xml:base="http://blog.viarails.net/">
    <author>
      <name>Wesley</name>
    </author>
    <id>tag:blog.viarails.net,2007-08-08:10</id>
    <published>2007-08-08T00:49:00Z</published>
    <updated>2008-02-26T21:16:47Z</updated>
    <category term="facebook webapps"/>
    <link href="http://blog.viarails.net/2007/8/8/facebook-garage-part-6" rel="alternate" type="text/html"/>
    <title>Facebook Garage - Part 6</title>
<content type="html">
            &lt;h3&gt;Demo: Carpool by: Rajat Suri&lt;/h3&gt;

Rajat explains how he produced the idea of Carpool, and how Facebook was the perfect (only?) platform to build it. Facebook already has the users, and it connects people that already trust each other (at least on some level).
&lt;p&gt;
The app is pretty cool, it shows rides offered and needed, how many miles the user has travelled, and how many CO2 emissions have been avoided by carpooling.  Rajat should talk to &lt;a href='http://zerofootprint.net'&gt;Zero Footprint&lt;/a&gt; about this  :)
&lt;/p&gt;


&lt;h3&gt;Demo: My Aquarium by Greg Thomson&lt;/h3&gt;
&lt;p&gt;
This developer's applications have a total of 2.6 million users and 75,000 new users per day. (wow!) 
&lt;/p&gt;
&lt;p&gt;
 Greg talked about profile updates, which apparently have a failure rate of 5%. He solved the problem by having a queue that runs all of the time, attempting requests until they succeed.
&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://blog.viarails.net/">
    <author>
      <name>Wesley</name>
    </author>
    <id>tag:blog.viarails.net,2007-08-08:9</id>
    <published>2007-08-08T00:19:00Z</published>
    <updated>2008-02-26T21:19:14Z</updated>
    <category term="facebook webapps"/>
    <link href="http://blog.viarails.net/2007/8/8/facebook-garage-part-5" rel="alternate" type="text/html"/>
    <title>Facebook Garage - Part 5</title>
<content type="html">
            &lt;h3&gt;Updating the Facebook Profile.  by Colin Smillie&lt;/h3&gt;
&lt;div&gt;
Rules:
&lt;ul&gt;
  &lt;li&gt;content rules
    &lt;ul&gt;&lt;li&gt;no iframes, or auto-running flash&lt;/li&gt;&lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;display rules
     &lt;ul&gt;&lt;li&gt;consistent presentation and user experience&lt;/li&gt;&lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

Caching
&lt;ul&gt;
 &lt;li&gt;The profile page is cached, so your app must notify facebook in order to update the profile page.
 &lt;/li&gt;&lt;li&gt;See the fb:ref method for updates.&lt;/li&gt;
  &lt;li&gt;multiple handles are possible, so you could update many profiles at once (think of a horrorscope application, only 12 updates would need to be made for many users&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;

&lt;h3&gt;Application Demo: &quot;My Free Stuff&quot;, by: Ricardo Covo&lt;/h3&gt;
&lt;p&gt;
Ricardo presents his application which was developed with MS tools (dotNet + SQL Server). He also uses iframes, which seems to be less common.  Like Rails, dotNet has an API wrapper (several) for ease of use. 
&lt;/p&gt;&lt;p&gt;
Ricardo found the facebook platform to be extremely easy to develop for, and the api wrappers provide seamless integration into your own platform of choice.
&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://blog.viarails.net/">
    <author>
      <name>Wesley</name>
    </author>
    <id>tag:blog.viarails.net,2007-08-08:8</id>
    <published>2007-08-08T00:17:00Z</published>
    <updated>2008-02-26T21:40:28Z</updated>
    <category term="facebook webapps"/>
    <link href="http://blog.viarails.net/2007/8/8/facebook-garage-part-4" rel="alternate" type="text/html"/>
    <title>Facebook Garage - Part 4</title>
<content type="html">
            &lt;h3&gt;FQL: Overview by Craig Saila&lt;/h3&gt;
&lt;p&gt;
Facebook API calls are just embedded FQL calls. 
&lt;/p&gt;
&lt;div&gt;
Advanatages:
&lt;ul&gt;
  &lt;li&gt;common syntac for all methods&lt;/li&gt;
  &lt;li&gt;condense facebook queries&lt;/li&gt;
  &lt;li&gt;reduce response size&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
FQL is very similar to SQL. Sub selects are allowed, etc. 
&lt;p&gt;Ex:  SELECT current_location FROM user WHERE uid = 324324. This will return an XML response.
&lt;/p&gt;&lt;p&gt;
There are about two dozen tables that can be queried. The users table is most often queried.
&lt;/p&gt;&lt;p&gt;
FQL contains some helper functions that help with queries. It's quite PHP like. 
&lt;/p&gt;&lt;p&gt;
You can only query against &quot;indexable&quot; columns in your where statement. You need at least one in your query.
&lt;/p&gt;&lt;p&gt;
FQL is designed to be efficient, so no JOIN, ORDER BY, GROUP BY or LIMIT. Each FROM can only reference one table. You must also specify each field that you want the query to return (&quot;SELECT *&quot; is not allowed). Sorting of data, etc must be done on the application level.
&lt;/p&gt;&lt;div&gt;
Tips:
&lt;ul&gt;
&lt;li&gt;Use the developers tools (fql.query)&lt;/li&gt;
&lt;li&gt;Read the API docs&lt;/li&gt;
&lt;li&gt;Share what you learn on your blog or wiki&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
          </content>  </entry>
</feed>
