My Profile page: a RESTful single resource using Formtastic

I’ve just implemented the My Profile tab for Sano:

sano-018

Can I write 500 words about? Well, I can try.

I like using RESTful routes. In case you don’t know what they are let me try to explain it quick, at least the relevant part. You normally have a set of route rules that would point /movies to the movie listing, /movies/new to a form to add a new movie, /movies/123 to see the movie 123. With RESTful routes in Rails all that is done automatic in a single line:

map.resources :movies

What you are doing is defining a resource. The resource has several actions that can be performed on them:

  • index (a.k.a.: listing)
  • new
  • edit
  • create
  • update
  • destroy

In Sano I have a weights resource that is a very fine example of it:

map.resources :weights

Running the rake routes command we can see all the routes it generate:

    weights GET    /weights(.:format)          {:action=>"index", :controller=>"weights"}
            POST   /weights(.:format)          {:action=>"create", :controller=>"weights"}
 new_weight GET    /weights/new(.:format)      {:action=>"new", :controller=>"weights"}
edit_weight GET    /weights/:id/edit(.:format) {:action=>"edit", :controller=>"weights"}
     weight GET    /weights/:id(.:format)      {:action=>"show", :controller=>"weights"}
            PUT    /weights/:id(.:format)      {:action=>"update", :controller=>"weights"}
            DELETE /weights/:id(.:format)      {:action=>"destroy", :controller=>"weights"}

You see the (.:format) in there? That means that every route is also accessible in alternative formats. For example: xml. Go and try it, add some weights and access http://sano.pupeno.com/weights.xml.

If you are curious, the code for that is this:

def index
  @weights = user.weights.all

  respond_to do |format|
    format.html
    format.xml  { render :xml => @weights }
  end
end

I now want everything to be a resource. How can “my profile” be a resource? Well, it’s not hard. It’s not a collection resource, it’s a single resource. There’s no list of profiles, no creation of new profiles or destruction of profiles. There’s only editing and updating of a single profile (which is actually your user).

It turns out that in Rails, that’s very easy to define:

map.resource :profile, :only => [:edit, :update]

Notice how it says “resource” instead of “resources” and it only allows certain actions. Rails is really quite flexible here, logging in is also a resource. It’s called session and you can create them, by logging in, or destroy them, by logging out (no editing). There’s also an extra action needed by OpenID. This is the route definition:

map.resource :session, :only => [:new, :create, :destroy], :member => { :finish_creating => :get }

The “member” part specifies that action to be only for items, not for the whole collection. If it was a collection resource, you could have extra listings. The same way you have index, you could have sorted_index.

The form in the my-profile-page is an example of what Formtastic is good at. This is the whole form:

<% semantic_form_for @user, :url => profile_url do |f| %>
  <% f.inputs do -%>
    <%= f.input :name %>
    <%= f.input :email %>
    <%= f.input :height, :hint => "meters" %>
    <%= f.input :gender, :as => :radio, :collection => [["Male", false], ["Female", true]] %>
    <%= f.input :birthday, :start_year => 1900, :end_year => Time.now.year %>
  <% end -%>
  <% f.buttons do -%>
   <%= f.commit_button :label => "Update profile" %>
  <% end -%>
<% end %>

Special thanks to Ryan Bates who covered the gender case in Railscasts episode 184 and Eifion Bedford of ASCIIcasts for making it easy to find. It surely would have take me some time to figure it out.

Can you please update your profile on Sano?

There you go 553 words!

You may also like:


Leave a Reply

Hi, I'm Pablo, this is my web site. You can follow me or connect with me:

Or get new content delivered directly to your inbox.

Join 4,025 other subscribers

I'm writing a book

Stack of copies of How to Hire and Manage Remote Teams

How to Hire and Manage Remote Teams, where I distill all the techniques I've been using to build and manage distributed teams for the past 10 years.

I write about:

announcement blogging book book review book reviews books building Sano Business C# Clojure ClojureScript Common Lisp database Debian Esperanto Git history idea Java Kubuntu Lisp music Non-Fiction OpenID programming Python Rails rant re-frame release Ruby Ruby on Rails Sano science science fiction security self-help Star Trek startups technology Ubuntu video web Windows WordPress

I've been writing for a while:

%d bloggers like this: