BrunoMiranda.com

Personal Blog about Software Engineering, Design, Travel & More

About a week ago I put together a micro project called NaPicIt. Weirdly enough it stands for Name that Picture.

While posting some pictures online I found it difficult to remember the name of certain locations to describe the image. A thought came to mind. Wouldn’t it be great if someone else could help me describe this picture?

You can login via Twitter oauth authentication, where you don’t actually have to provide your credentials to anyone but twitter. Once you upload your picture, others can describe it. Once at least two descriptions match it shows up on the site.

Not sure how far I will take this, but I thought it was an interesting idea and a neat way to play with Twitter’s oauth.

A friend of mine, Davis Cabral helped me with some of the oauth implementation.

We have released the new Cyloop music platform built using Ruby on Rails. I have had the pleasure of working with the team at Hoodiny to build and deploy this great application.

The platform has been adopted by MSN Brazil and MSN Mexico for their default music channel, soon to be the default music channel for MSN Latin America, MSN US Latin and MSN Canada.

While being featured on the home page of MSN Brazil and MSN Mexico we witnesses a tremendous amount of traffic. We knew this was going to be the case which is why we spend a considerable amount of time pre release working on caching and optimizations.

One of my favorite features of the application is the ability to follow your friends and discover music based on what they are listening to, you can also follow you favorite bands. We are using a messaging queue platform called RabbitMQ to accomplish the queuing of activity (writes/reads). Another aspect of our caching strategy is heavy usage of Memcached coupled with warm-caching of the activity feeds which are currently being stored to flat files.

During the caching and optimization phase we implemented a separate messaging queue for emailing and image uploads, lots of rails page, action and fragment caching as well as strategic usage of rails metal and cache-money to enhance performance.

Many thanks to the entire team who worked on this application. The Hoodiny dev team (Scott, David, Steven, Rick, Ana), the Hashrocket team, and Jason Seifer for bringing his rails scaling insight to the table. Also many thanks to Engine Yard and all the excellent application support technicians who helped up configure our cluster.

More to come, thank you and may we see continued success.

RubyOnda is a ruby news website in portuguese built by myself and Roberto.

Today Felipe Mesquita built a nice little widget for those interested in showcasing the latest community news posted to RubyOnda on their own site.

The code to insert the widget is:

< script src="http://rubyonda.com/widget-embedded.js" type="text/javascript">

Here is what it looks like:

I kept seeing tweets and comments about different upcoming conferences and decided to put together a small list.

Ruby Hoedown
August 8-9, 2008 - Huntsville, AL

erubycon
August 15-17, 2008 - Columbus, OH

RailsConf Europe
September 2-4, 2008 - Berlin, Germany

Love Star Ruby Conference
September 4-6, 2008 - Austin, TX

WindyCityRails
September 20, 2008 - Chicago, IL

Rails Summit Latin America
October 15-16, 2008 - Sao Paulo, Brazil

Rubyconf
November 6-8, 2008 - Orlando, FL

Voices that Matter
November 17-20, 2008 - Boston, MA

Let me know if I have missed any and I’ll update the list.

Sponsored in part by:

To be held in São Paulo, Brazil, the summit holds an incredible line-up of speakers such as, Chad Fowler, Jay Fields, Chris Wanstrash, David Chelimsky, Obie Fernandez and many more. The summit takes place in this beautiful venue which is located in the heart of Brazil on October 15-16.

The cost of the event is about $190 USD ($300 Brazilian Reals). The auditorium is located midtown with access to metro and plenty of public transportation. Hotels around the area are selling out fast as the conference is expected to gather around 700 attendees.

If you can make it don’t miss it. While you are down there, make it a vacation out of it. Brazil is a beautiful country with great beaches, food, and lots of fun.

São Paulo

Signup Today
Rails Summit Latin America

For those of us who work on various rails apps during the course a week this script is a lifesaver. I always ran into small issues related to having multiple apps running on development mode on on the same domain.

Most of the apps I deal with on the regular basis require authentication. Each site has a different login/password combination that safari is set to pre-fill. The problem with that is safari, or any other browser, has a hard time spotting the difference between http://0.0.0.0:3000 and http://0.0.0.0:3000. Possibly because they are the same address.

Another issue you may possibly encounter is that if you use some some of automatic time tracking tool like RescueTime (which is awesome) it will not be able to tell the difference between apps either (in case you wanted to tag them differently)

/etc/hosts to the rescue

Step one is to edit you /etc/hosts line:

127.0.0.1 localhost

to

127.0.0.1 localhost myblog clientone yasn

What that step gives you is the ability to browse the to the development version of you app running on any port on localhost at http://myblog:3000.

This will allow the browser to record and auto-fill proper passwords and will also allow RescueTime to properly identify the domains.

This is cool but could become tedious, boot app, open browser, type address (you could bookmark it but still).

#!bin/bash to the rescue

I created a file called go that takes 2 params, the first on is the name of the app that matches the name you gave it on /etc/hosts. Both params are optional the domain will default to 0.0.0.0 and port number to 3000.

Go does a couple of things, it boots the server (webrick or mongrel) on the specified port, opens a safari window and browses to the correct URL supplied as the first param.

#!/bin/bash

if [ -n "$1" ]; then
  SITE=$1
else
  SITE=0.0.0.0
fi

if [ -n "$2" ]; then
  PORT=$2
else
  PORT=0
fi

sleep 3 && open /Applications/Safari.app http://$SITE:300$PORT & script/server -p 300$PORT

Save that anywhere you’d like, preferably a folder included in your path make it executable and you are done.

Now from the prompt inside you app you can run go myblog 1 and that will boot the server on port 3001, open safari and browser to http://myblog:3000.

I am sure this can be massively improved upon. If you have an idea or would like to add to the script please let me know.

Rails 2.1 was released about 2 weeks ago at RailsConf 2008 in Portland, OR. Before we could even make it home Carlos Brando and Marcos Tapajos released the portuguese PDF version of their Rails 2.1 book as a free download.

Shortly after that the book was translated into english with the help of a couple of community members and also released a a free download. I had the pleasure to help these guys with the grammar review of the second edition english version of the book.

If you enjoy the book make sure to recommend these guys:

Carlos Brando , Marcos Tapajos , Rafael Barbosa , Caike Souza, Pedro Pimentel , Abraão Coelho, Ricardo S Yasuda and myself Bruno Miranda.

Since arriving in Portland, OR this past wednesday the weather has cleared up. Today, Saturday it is mighty sunny and 65 degrees outside. The city is beautiful, the light rail (tram) transportation service is awesome, if it wasn’t for the gloomy weather almost all year around I would seriously consider moving here.

Thursday was tutorial day, the meta-programming tutorial by Neil Ford was great, really interesting concepts. The afternoon tutorial of my choice was average, so much so that I already forgot what it was about.


Photo by: Duncan Davidson

Joel Spolsky opening keynote on Friday was great, he talked about writing software that makes people happy. “Blue Chip” software, really motivating. Friday night David Heinemeier Hansson spoke on the Rails Community surplus and how he feels it will not last forever. He adviced the community to use it wisely: “Don’t spend the surplus in hookers and fur coats.”

So far there have been many mentions to Tasty Planner in numerous talks. Josh’s talk about Building a web app in 48 hours happens tomorrow at 10:45am.

The talks have been much better than last years. As the community grows, it also matures and topics seem more advanced. Jeremy Kemper’s talk was great, showcasing what’s new in 2.1. Optimizing Rails by Michael Koziarski was full of goodies and the panel by Blaine Cook, Bradley Taylor, Ezra Zygmuntowicz, Jim Meyer and Kevin Lawyer brought to the surface interesting points about scalability topics (I apologize about the crappy sound).


Scaling Rails - RailsConf 2008 from Bruno Miranda on Vimeo.

We paid a much deserved visit to Henry’s 12th St Brewery and Dough Fir, if you have not been to those places, you haven’t really been to Portland.

I am looking forward to watching Kent Beck’s keynote tonight as I have recently finished reading his great book: Extreme Programming Explained.

Here are some iPhone Conference Pictures.

Conference meals have been great. Attendance seems to be the a record, approximately 2000 I heard. Wifi is below average but stable, the community is great and seems to be more united than ever, the message board has about a million job offer notes as shown in the pics below:

More to come soon.

I can imagine you have seen lots of posts about this subject. Well here is another one. For anyone who has used script/generate rspec_scaffold in the past knows that it generates a lot of specs for your controller and views.

Here is a list of issues I have with the auto-generated specs. They are very wordy. Almost 50 lines for the controller update action. Over 60 lines for testing routes. The majority of testing performed is related to testing the framework’s functionality, which in my opinion is not necessary. Another problem I have with it is the fact that as soon as you start nesting resources most of your specs will fail. You will have to adjust them to understand the new nesting setup you have going on. That is just too much busy work if you ask me. You end up spending a bunch of time chasing failing specs, and your code to test ratio will besomewhat inaccurate at the end.

So what should you spec? Well let’s start with the controller. I generally use rspec_controller instead of scaffold since it does not generate an ocean of framework specs. All I really test in the controller are new methods I write, for example, a search or order method. Important sidenote: if a controller method is broken, write a spec for it and watch it fail, when you fix it and the spec passes you will know if that method ever goes belly up again.

The views can also be a pain. The rspec scaffold creates a ton of view specs based on the scaffolded view, which is generally really unlike the real view you will end up with in your app. I generally stay away from those puppies and only write view specs for important components I’d expect the view to either have or not have such as, admin links.

If you follow the skinny controller fat model golden rule, your model should contain most of the application logic. This is where your specs will rule. Make sure you have high coverage for all methods in your model. Hopefully they will do most of the heavy lifting; these should be well spec’out.

Really spend the time to spec your helpers. They will most likely be used numerous times in your application and this will save you a ton of time otherwise spent chasing bugs.

In closing, check you test coverage with rcov.

gem install rcov
rake spec:rcov

This will generate a coverage report in /coverage.

You can also run rake stats to get your code to test ratio. If you follow the above guidelines, you should expect to see something close to 1:1 or less since you are not spec’ing controller/routes/views as aggressively as rpec_scaffold does.

As many of you are doing, I moved a couple of my source repositories to GitHub. At the moment I have one private and one public.

Here is a simple guide to deploy using vlad. You will need a condig/deploy.rb file:


set :application, "appname"
set :domain,      "domain.com"
set :deploy_to,   "/var/rails/#{application}"
set :scm,         "git"

# use the following with a private repos
# set :repository,  "git@github.com:user/appname.git"

# use the following with a public repos
# set :repository,   "git@github.com:user/appname.git"

set :mongrel_port, 8070
set :mongrel_servers, 2

namespace :vlad do
  desc 'Runs vlad:update, vlad:symlink, vlad:migrate and vlad:start'
  task :deploy => ['vlad:update', 'vlad:symlink', 'vlad:migrate', 'vlad:stop_app', 'vlad:start_app']

  desc 'Symlinks your custom directories'
  remote_task :symlink, :roles => :app do
    run "ln -s #{shared_path}/database.yml #{current_release}/config/database.yml"
  end
end

Possible Gotchas!

If you have Vlad 1.2 installed you will need to add the following to your Rakefile

begin
  require 'vlad'
  Vlad.load :scm => "git"
rescue LoadError
  # do nothing
end

If you run into the following error:

fatal: You must specify an archive format

It is probably because you installed git-core with sudo apt-get install git-core. The reason for that is apt-get install git-core installs a 1.4x version of git on your Ubuntu machine, and a default for git archive was added in a later version. Thankfully the solution is pretty simple. Remove the previously installed version of git-core and install a newer version from source.

sudo apt-get remove git-core
wget http://kernel.org/pub/software/scm/git/git-1.5.5.1.tar.bz2
sudo apt-get build-dep git-core
tar xjf git-1.5.5.1.tar.bz2
cd git-1.5.5.1/
./configure --with-tcltk
make
sudo make install

Use –with-tcltk since there is no need to install GUI on the server.

If you do however want to install GUI for some reason you will need to install gettext and start the the git-core installation from source from the beginning.

sudo apt-get install gettext

Now all you have left is to run setup and then deploy:

rake vlad:setup

and

rake vlad:deploy

Deploying a Private Repos

Make sure you go into the server, generate an ssh key for the deployment user and paste the public key into the Github’s deploy key. You will also need to go into the server and clone the repos so that the ssh key pair is generated. Make sure the public key on the server is owned by the deploy user and the permissions are correct:

chown deploy:deploy id_rsa.pub

and

chmod 600 id_rsa.pub

Let me know if you encounter any issues with the instructions above.

While developing rails applications I find myself starting and stopping mongrel a bunch of times. At Todobebé we have 4 different apps to deal with and sometimes I want to start and stop a couple of them in succession.

I put together a couple of quick aliases in my .bash_profile to help me with that process. All I have to do now is browse to app root, and type

ss
that causes the server to start, brings up a browser window with a new tab and browses to http://0.0.0.0:3000.

I have also create ss1 and ss2, you can have as many as you would. Here is how I did it.

alias ss="sleep 3 && open /Applications/Safari.app 
http://0.0.0.0:3000 & script/server -p 3000"

alias ss1="sleep 3 && open /Applications/Safari.app 
http://0.0.0.0:3001 & script/server -p 3001"

alias ss2="sleep 3 && open /Applications/Safari.app 
http://0.0.0.0:3002 & script/server -p 3002"

If you are wondering why your flash is not getting cleared in case you use some sort of cacheable plugin or anything of that matter.

The method to clear the flash previously called

clear
was recently renamed to
discard

Since I can never seem to be able to find a bookmarked site when I need it. I have decided to post am entry here every time I find something extremely useful.

Today while listening to the Rails Envy podcast I was amazed at how many useful links I those guys were talking about.

One of the most interesting ones was the Rails security cheatsheet.

So you are adding comments to your app and you would like to provide live preview functionality. There is a simple and effective way to do it.

Lets start by creating a new comment form:

New Comment
<-% form_for(@comment) do |f| %>
  <-%= render :partial => 'form', :locals => {:f => f} %>   
  <-%= f.submit "Save Comment" %>
<-% end %>

Now we need to write an observer to watch our form for changes. It’s important that your form has an unique id, such as “new_comment”.

<-%= observe_form "new_comment",     
:frequency => 2,
:update => "live_preview",
:complete => "Element.show('live_preview')",
:url =>  { :controller => 'comments', :action => 'preview' } %>

Note in the observe_form method above you tell it update “live-preview” every 2 seconds. Create a div with an id of live_preview and set it’s display property to none.

Next create a preview method in your comments controller

def preview
  render :layout => false
end

The next step is to create a view that will be used to display your live preview data. I called my view preview.html.erb.

Your Comment: <-%= params[:comment][:body] %>

You will also need to add a route if you are using rails edge for the preview action:

map.preview 'comment_preview', :controller => 'comments', 
:action => 'preview'

That should be enough to setup a simple live preview.

Enjoy!

Model observers are useful for when you are trying to extend the class with functionally that is not directly connected to the DB model.

For example, you would like the app to send out an welcome email when a new user signs up. Emailing the member has no connection to the database table you are trying to model.

So you could create a MemberObserber as such:

ruby script/generate observer Member

That generator will create a file called member_observer.rb inside you app/models folder, which will look something like this:

class MemberObserver < ActiveRecord::Observer

end

You may now add a after_create method inside the class above. That method will be called after a member record is created.

class MemberObserver < ActiveRecord::Observer
    def after_save(member)
    AuthenticationMailer.deliver_welcome_email(member)
    end
end

If you name your observer the same as you model, rails will automatically set it to observe your model. You can however call it something different and manually specify what to observe, as such:

class MailerObserver < ActiveRecord::Observer
  observe  Member
  observer Reminder
end

Enjoy!

Well, after 48 hours of coding, we finally finished our app.

We decided to create a recipe/shopping manager called Tasty Planner.

Tasty Planner was built using Ruby on Rails in forty eight hours by a team of three dedicated code monkeys, Josh Owens, Chris Saylor, Bruno Miranda and designed by Kevin Burg. Give Tasty Planner a try, like it? We would appreciate it if you registered and voted for us on the Rumble site.

We will continue to improve the application in the next, week, you can expect to see lots of improvements.

Don’t forget to vote for us, thanks!

Some of you may have participated or heard about last year’s Rails Day 2006. The contest allowed developers to design and implement a web application in a 24 hour period. In exchange for prizes and a bit of community recognition.

Although the contest was partially successful, and many interesting apps came out of it, this year’s Rails Rumble, September 7-8, 2007, organizers decided to do it differently.

rails rumble sticker

Rails Rumble will allow a 48 time period for app development and deployment. The teams will be made up of 1-4 developers and there is currently a max of 50 teams. Applications will be judged by their completeness, user interface, originality, usefulness and overall.

The event includes sponsorships by Pragmatic Bookshelf, Cashboard, Active State so good prizes are expected.

If you are a rails developer, and would like to participate run over to Rails Rumble and sign up.

I was unaware of this until recently so you might find it useful.

You can create a list of all your favorite rails plugins at Agilewebdevelopment.com and use RaPT to install the entire list into a newly created rails app.

To install RaPT:

sudo gem install rapt

Go to agilewebdevelopment.com, login and add plugins to your favorites. The site will provide you with a unique url that you can use to install the pack of plugins.

rapt pack:install http://agilewebdevelopment.com/favorites/
pack/243610d6bf75

Enjoy.

In preparation for my presentation next Monday, July 23, I set out to install and configure Capistrano 2 and ssh locally (OS X) so that I can demonstrate the deployment of a Rails app using Capistrano 2.

I followed the instructions online, setting up a new user called deploy, starting up the ssh server for that user and making sure that all PATH were correct.

A way to test your paths is running

echo $PATH

The above should return the location for the binaries for to ruby, rake, gem, etc are located.

Mine did so, I thought life was great. I created the following recipe:

load 'deploy' if respond_to?(:namespace)

require 'mongrel_cluster/recipes'

set :application, "hello"
set :domain, "localhost"
set :repository, "file:///Users/Bruno/svn/hello/"
set :deploy_to, "/Users/deploy/www/sites/#{application}" 
set :user, "deploy"
set :use_sudo, false
set :scm, :subversion
set :scm_command, "/usr/local/bin/svn"

role :app, domain
role :web, domain
role :db,  domain, :primary => true

namespace :deploy do

  desc "Run after every successful deployment." 
  task :after_default do
    cleanup
  end

  desc "Restart Mongrel"
  task :restart, :roles => :app do
     run "cd /Users/deploy/www/sites/hello/current/ && script/server"
   end

end

Which should be enough to properly deploy and start the mongrel server. That was not the case. I kept getting errors related to cap not being able to find the path to rake or rubygems.

With the help of my fried Chris Saylor, I created a task to inspect the system variables:

  desc "Debug task."
  task(:debug_env) { run "env" }

Upon running the task above I noticed that the path= line was not showing the proper path to where my binaries where located. It should have been:/usr/local/bin

It turns out that I had to set create an ssh environment path in ~/.ssh/environment

PATH=/usr/local/bin:/usr/bin:/usr/sbin

Also, you will need to edit /etc/sshd_config, uncommenting the line that states: PermitUserEnvironment no, and changing the value to yes.

#
PermitUserEnvironment yes
#

After those changes have been made, you should be able to run:

cap deploy:setup
cap deploy

Enjoy!

PS. Thanks to everyone that had the patience to put up with me while I pulled my hair out for 2 days trying to find the answer to this problem, that includes, voxdolo, cwsaylor and queso.

Michel Barbosa published his thesis on key adoption factors and demographic characteristics of companies already using Ruby on Rails.

He conducted extensive research and survey on a large number of companies that have already adopted Ruby on rails as their development framework.

My good friend Chris Saylor gave a presentation on jump-starting Ruby on Rails.

Here is the video

Here are the PDF slides.

Our next Miami Ruby Meetup will be on July 16, location is still not confirmed but it will be near the Datran building.

I will be giving a presentation of Capistrano 2.

While searching for a couple of rake script shortcuts today I came accross a great Rail cheatsheet at the RubyOnRailsBlog.com

Rails Cheatsheet

The cheatsheet is very complete and insanely useful. Go check it out for yourself.

If you a trying to validate if the value of an attribute is unique on the database, you can easily accomplish this by using the built in helper method…

validates_uniqueness_of
But how would you go about making sure the attribute value is unique based on a scope parameter? Let’s say you are building a holidays table and need to make sure you only allow one ‘Christmas’ holiday to be created per year:
  validates_uniqueness_of :name, 
:scope => :year, :message => "must be unique"

Hope that helps!

I’ve been looking for a way to limit the number of options under minute on timeselect and datetimeselect. You can set the :minute_step to 15 which will give you: 00, 15, 30 and 45.

<%= datetime_select 'game', 'game_date_time', {:minute_step => 15} %>

Hope that helps!

If you need to display a a float/string formatted as money (with two decimal points), simply add a helper method to your application_helper.rb.

module ApplicationHelper
  def two_dec(n)
    sprintf("%.2f", n)
  end
end

Now every time you need to display you value, just pass it into the two_dec method.

  $<%= two_dec(@repair.cost) %>

Will produce: $150.00.

I couldn’t count how many times per day I have to reference the Rails API. RailsBrain makes it easy to quickly find what you are looking for.

Visit the Archives →