Rails on the Run

Rails experiments by Matt Aimonetti

Browsing Posts tagged api

update Nov 11: the gem is finally available there or simply:

  sudo gem install googlecharts

Note that I’m working on merging this gem with another Google Charts gem. (see comments for more info about that)


I’ve been working on a Google Chart Gem that I have ready for a beta release but unfortunately, getting a new project setup on RubyForge takes forever. (apparently 72 hours)

It’s mainly a wrapper for the great GChart API, but instead of using a helper to generate your graphs, you can simply do:

  Gchart.bar(:title => 'My Mojo', :data => [1,2,4,67,100,41,234], :max_value => 300, :bg => 'c3c3c3')

  Gchart.line(:title => 'My Mojo',
              :data => [[1,2,4,67,100,41,234],[41,63,96,17,100,14,423]],
              :bg => '666666',
              :graph_bg => 'cccccc',
              :line_colors => 'ff0000,00ff00',
              :legend => ['morning','evening'])
  Gchart.pie(:data => [20,10,15,5,50], :title => 'SDRuby fu', :size => '400x200', :labels => ['matt', 'rob', 'patrick', 'jordan', 'ryan'])


As far as I know this is most complete Ruby wrapper for Google Chart API, but feel free to look around.

I recently had to deal with an interesting challenge. I had to write a simple interface between a rails app and a Flash application. Nothing hard and if you browse the archives, you’ll find examples and tutorials on how to create a REST interface to communicate between Rails and Flash.

The thing was that this time I had to interface with a model using attachmentfu. I’m a great fan of afu and it’s definitely the best way of dealing with uploads.

My model looked more or less like that:

class Photo < ActiveRecord::Base

belongs_to :user

    :content_type => :image,
    :storage => :file_system,
    :max_size => 10.megabytes,
    :resize_to => '640x480>',
    :thumbnails => { :thumb => '100x100>',
                              :preview => '300x200>',
  # read more about validates_existence_of http://blog.hasmanythrough.com/2007/7/14/validate-your-existence
  validates_existence_of :user

My show action in my photo controller could have looked a bit like that:

respond_to do |format|
  format.html # show.html.erb
  format.xml  { render :x ml => @photo }

That’s great, the problem is that we are displaying a lot of information that our Flash client doesn’t need to see, actually we are exposing a lot of information nobody should ever see and we are not displaying what we should. On top of being a waste of bandwidth and giving too much work to the client, we are not actually providing the user with the details of the thumbnail.

The first thing to do would be not to display some of the object attributes, the to_xml method lets you do that.

Note that in Edge, Rails will automatically try to convert your object using toxml, you don’t even need to mention it. However in our case, we want to use some _advanced features offered by to_xml, and here is how our code should look like:

format.xml do
  render :x ml => @photo.to_xml( :except => [ :id, :filename, :updated_at, :user_id, :height, :width], :skip_types => true )

What I just did is very simple, we rendered our object as an xml object but we didn’t convert few attributes, :id, :filename, :updatedat, :userid, :height, :width. By default Rails also adds the object type, we don’t really need that right now, so let’s skip them.

(The reason why I don’t want to convert the filename is that I want to provide our Flash client with the photo thumbnail instead of the original picture.)

As far as I know, to_xml doesn’t let you create new attributes. (if I have some time, I’ll submit a patch to get that added).

What we are trying to do is to display the avatar of a user. We found the photo record using @user.photo but that’s the original photo and we want to provide Flash with the avatar info, not the original.

What we need to do is to simply add a new attribute called avatar:

format.xml do
  @photo[:avatar] = @photo.public_filename(:thumb)
  render :x ml => @photo.to_xml( :except => [ :id, :filename, :updated_at, :user_id, :height, :width], :skip_types => true )

Simple enough, but it took me a little while to figure it out ;)

Voila, we now have a clean, trimmed and safe XML returned object that you can be consumed by our Flash client. Ohh, and we added a new attribute that the original object didn’t have :)