Ao utilizar o scaffold do Rails, ele criará todos os métodos necessários no controller. Depois que o usuário preenche os dados do formulário e envia, é executado o método create do controller. Este método faz algo semelhante ao código abaixo (no exemplo é um CRUD de usuário):

@usuario = Usuario.new(params[:usuario])

Na forma em que o Rails cria o formulário, os atributos do usuário são passados ao controller como um hash. O valor do params acima é algo parecido com isso:

{ "authenticity_token" => "xI1Cy+LvUZzg6FR/1Y/JHcaHVPRyWsHmRII8BhMOr0E=",
 "utf8" => "?",
 "action" => "create",
 "controller" => "usuarios",
 "usuario" => { "nome" => "Novo usuario", "email" => "[email protected]" } }

Além da definição do token de segurança, codificação em utf-8, nome do controller e da action que será executada, o parâmetro usuario contém todos os atributos que foram preenchidos no formulário. Desta forma, é muito simples atribuir os parâmetros preenchidos a um objeto Usuario, seja criando um novo (@usuario = Usuario.new(params[:usuario])) ou editando (@usuario.update_params(params[:usuario])). O Rails chama isso de mass assignment.

O problema desta abordagem é que o usuário poderia facilmente inserir novos parâmetros neste hash, simplesmente adicionando tags input hidden no formulário (usando o Firebug, por exemplo):

<input type="hidden" name="usuario[admin]" id="usuario_admin" value="true" />

Adicionando o código acima, o novo usuário criado receberia o valor true no atributo admin, o que representa uma falha grave na segurança da aplicação.

O Rails oferece um mecanismo para garantir a segurança nestes casos, usando os métodos attr_protected e attr_accessible do ActiveModel. O primeiro permite definir atributos que não podem ser alterados através de mass assignment:

class Usuario
  attr_protected :admin
end

E o attr_accessible é uma forma mais segura: somente os atributos passados para este método poderão ser alterados com mass assignment. Os demais ficam protegidos:

class Usuario
  attr_accessible :nome, :email
end

Obviamente estes dois métodos não podem ser usados simultaneamente, pois um exclui o outro.

Se você quiser atualizar um objeto com mass assignment ignorando a segurança fornecida pelo attr_accessible e pelo attr_protected, basta utilizar o parâmetro without_protection (somente no Rails 3.1):

Usuario.create(
  {:nome => "Novo usuario", :email =>"[email protected]", :admin => true},
  :without_protection => true)

No exemplo acima, o usuário criado terá o atributo admin igual a true, mesmo que tenha sido usado o método attr_protected ou o attr_accessible para evitar a alteração deste atributo.

Outra opção interessante para evitar a alteração de atributos indesejados é o método attr_readonly. Os atributos passados para este método só poderão ser definidos na criação do objeto, e não poderão ser alterados depois. Porém, este método faz parte do ActiveRecord::Base, e não do ActiveModel, ou seja, ele não estará disponível se você usar outro ORM. Há uma issue aberta no Github solicitando que este método seja movido para o ActiveModel.

Link relacionado: Recebendo dados do usuário: attr_accessible e attr_protected


O Google Calendar é uma excelente ferramenta para manter o controle de compromissos pendentes. Porém, tem dois problemas: é limitado a tarefas que tenham uma data específica e não dependem do usuário concluir, ou seja, uma tarefa que foi programada para ontem mas não foi realizada não aparecerá mais no meu calendário (ou melhor, aparecerá no dia em que estava prevista, e provavelmente será esquecida com o tempo). Isso acontece porque o Google Calendar não é uma ferramenta voltada para tarefas, e sim para eventos. Para realizar o controle de tarefas, o melhor é utilizar uma ferramenta específica para tal. Idealmente uma que seja integrável ao Google Calendar, pois este continua sendo uma excelente ferramenta para controle de eventos (visualizar eventos futuros, compartilhar com outras pessoas, etc).

A opção mais óbvia para controle de tarefas seria o Google Tasks, pois é do próprio Google, e como tal, é totalmente integrado não só ao Google Calendar, mas também ao Gmail. Apesar de ser uma boa opção, o Google Tasks é bastante limitado, e não possui (ainda) uma funcionalidade que considero básica para uma ferramenta de controle de tarefas: o cadastro de tarefas recorrentes (ex: toda segunda-feira, todo mês no dia 10).

Em função destas limitações, eu prefiro utilizar o Remember the Milk, que é uma ferramenta muito mais completa que o Google Tasks. Ele também pode ser integrado tanto ao Gmail quanto ao Google Calendar.

Integração com Google Calendar

A integração é bem simples, através da interface iCalendar do Remember the Milk: vá até a opção settings, aba Info. Copie o link iCalendar Events Service (All Lists). Em seguida, vá ao Google Calendar, em other calendars, à esquerda, há uma opção Add by URL. Cole a URL que foi copiada do Remember the Milk, e será criado um novo calendário com as suas tarefas - obviamente só aparecerão as que tem data.

Apesar de funcionar bem, a integração é limitada: a hora da tarefa não aparece, não há link direto para ver a tarefa no RTM, e é somente uma visualização, ou seja, não é possível editar, excluir ou concluir a tarefa a partir do Google Calendar. Além disso, quando uma tarefa é concluída, ela demora um tempo para sumir do calendário. Mas é possível configurar reminders para este calendário específico, o que torna a integração mais útil.

O calendário criado exibe todas as tarefas do seu RTM que não estão concluídas e tem data. Outra possibilidade é criar calendários com listas específicas. Para isso, vá ao RTM, faça uma busca ou selecione uma lista ou smart list específica. No lado direito aparecerá uma opção iCalendar (Events). Copie esse link e repita o procedimento anterior no Google Calendar.

O RTM também disponibiliza dois gadgets para Google Calendar:

  • Sidebar Gadget

    Permite visualizar, editar e adicionar tarefas diretamente no Google Calendar. Só não é possível visualizar e editar notas, mas há um link para exibir no RTM.

  • Daily Gadget

    Adiciona um botão a cada dia do calendário; ao ser clicado, exibe a lista de tarefas do dia.

Integração com Gmail

O RTM disponibiliza duas maneiras de exibir as tarefas no Gmail:

  • Gadget do Google Calendar

    Se você configurou a integração do RTM com o Google Calendar, descrita acima, o gadget do Google Calendar exibirá as tarefas do RTM.

  • Gmail Gadget</li>

    Este gadget possui as mesmas funcionalidades do Sidebar Gadget para Google Calendar.

  • Add-on (Firefox e Chrome)</li>

    Esta extensão é bem semelhante ao Gmail Gadget, mas possui algumas funcionalidades a mais: ela pode ser configurada para criar tarefas automaticamente quando um email for marcado com estrela ou com um label específico. Também é possível criar uma tarefa associada a um email específico, que será automaticamente concluída quando o email for respondido.


O RVM já se tornou a opção padrão para gerenciar múltiplas versões de Ruby. Ele permite instalar várias versões, alternar entre elas, instalar gems em cada versão independentemente… mas não funciona em ambiente Windows. Eu sei que este não é um ambiente muito popular para desenvolvimento Ruby, mas existem usuários de Windows (seja por opção ou por obrigação) programando em Ruby. Para estes, uma alternativa ao RVM é o Pik.

O Pik funciona de forma bastante semelhante ao RVM. Para instalá-lo, primeiro é necessário instalar o Ruby Installer, um pacote pré-configurado especialmente para instalar o Ruby no Windows. A documentação do Pik recomenda a versão 1.8.7. Em seguida, instale as gems rake, isolate e o próprio pik:

gem install rake isolate pik

Antes de instalar o isolate, talvez seja necessário atualizar o Rubygems com o comando abaixo:

gem update --system

O próximo passo é instalar o Pik no diretório de sua preferência. Um detalhe importante que já me custou um bom tempo é que o path completo não deve conter espaços. Execute o seguinte comando para instalar em C:\Ruby\pik, por exemplo:

pik_install C:\Ruby\pik

Concluída a instalação, o comando pik help commands exibe uma lista com os comandos disponíveis. Quem já usou o RVM não terá dificuldades, pois os comandos são bem semelhantes. Os comandos mais comuns são:

  • pik install ruby/jruby/ironruby [versão] -> instala a versão desejada do Ruby, JRuby ou IronRuby. A versão é opcional; se for omitida, será instalada a versão mais recente. Importante: antes de executar este comando, instale o 7zip e adicione-o ao path
  • pik list -> exibe as versões de Ruby atualmente instaladas
  • pik use [versão] -> seleciona uma versão instalada
  • pik gem [comando] -> executa um comando do Rubygems em todas as versões instaladas
  • pik ruby [parâmetros] -> executa Ruby em todas as versões instaladas

Inicialmente, o comando pik list exibe apenas a versão 1.8.7:

C:\Ruby\pik>pik list
* 187: ruby 1.8.7 (2011-02-18 patchlevel 334) [i386-mingw32]

Decidi instalar a última versão do Ruby e do JRuby. Após instalar estas duas versões, a saída do comando pik list ficou assim (o asterisco mostra a versão atualmente em uso):

C:\Ruby\pik>pik install ruby
...
C:\Ruby\pik>pik install jruby
...
C:\Ruby\pik>pik list
  161: jruby 1.6.1 (ruby-1.8.7-p330) (2011-04-12 85838f6) (Java HotSpot(TM) Client VM 1.6.0_24) [Windows XP-x86-java]
* 187: ruby 1.8.7 (2011-02-18 patchlevel 334) [i386-mingw32]
  192: ruby 1.9.2dev (2010-05-31) [i386-mingw32]

Para selecionar o JRuby, por exemplo, use o comando pik use 161 (é importante lembrar que neste caso os comandos mudam de nome: irb vira jirb, ruby vira jruby):

C:\Ruby\pik>pik use 161

C:\Ruby\pik>ruby -v
'ruby' não é reconhecido como um comando interno
ou externo, um programa operável ou um arquivo em lotes.

C:\Ruby\pik>jruby -v
jruby 1.6.1 (ruby-1.8.7-p330) (2011-04-12 85838f6) (Java HotSpot(TM) Client VM 1.6.0_24) [Windows XP-x86-java]

Para instalar gems, basta usar o comando gem install normalmente. A gem será instalada na versão atual do Ruby (ou seja, a que você selecionou com o comando pik use). O comando pik gem permite instalar uma gem em todas as versões:

C:\Ruby\pik>pik gem install mongo
jruby 1.6.1 (ruby-1.8.7-p330) (2011-04-12 85838f6) (Java HotSpot(TM) Client VM 1.6.0_24) [Windows XP-x86-java]

Fetching: bson-1.3.1-jruby.gem (100%)
Fetching: mongo-1.3.1.gem (100%)
Successfully installed bson-1.3.1-java
Successfully installed mongo-1.3.1
2 gems installed

ruby 1.8.7 (2011-02-18 patchlevel 334) [i386-mingw32]

Fetching: bson-1.3.1.gem (100%)
Fetching: mongo-1.3.1.gem (100%)
Successfully installed bson-1.3.1
Successfully installed mongo-1.3.1
2 gems installed
Installing ri documentation for bson-1.3.1...
Installing ri documentation for mongo-1.3.1...
Installing RDoc documentation for bson-1.3.1...
Installing RDoc documentation for mongo-1.3.1...

ruby 1.9.2dev (2010-05-31) [i386-mingw32]

Successfully installed bson-1.3.1
Successfully installed mongo-1.3.1
2 gems installed
Installing ri documentation for bson-1.3.1...
Installing ri documentation for mongo-1.3.1...
Installing RDoc documentation for bson-1.3.1...
Installing RDoc documentation for mongo-1.3.1...

O comando pik ruby permite executar um código em todas as versões instaladas, útil para verificar incompatibilidades entre as versões, como por exemplo o construtor com parâmetros da classe Time:

C:\Ruby\pik>pik ruby -e "puts Time.new('2011-01-01')"
jruby 1.6.1 (ruby-1.8.7-p330) (2011-04-12 85838f6) (Java HotSpot(TM) Client VM 1.6.0_24) [Windows XP-x86-java]

ArgumentError: wrong number of arguments (1 for 0)
  (root) at -e:1

ruby 1.8.7 (2011-02-18 patchlevel 334) [i386-mingw32]

-e:1:in `initialize': wrong number of arguments (1 for 0) (ArgumentError)
        from -e:1:in `new'
        from -e:1

ruby 1.9.2dev (2010-05-31) [i386-mingw32]

2011-01-01 00:00:00 -0200

Mais detalhes sobre o funcionamento do Pik podem ser encontrados no Github do projeto.


A principal característica de projetos open source é que qualquer pessoa pode contribuir com eles. Geralmente quando falamos em contribuir com este tipo de projeto, logo pensamos em código fonte - corrigir um bug ou implementar uma melhoria. Mas na verdade podemos contribuir de várias formas (para mais informações sobre o modelo open source, recomendo a leitura do famoso artigo The Cathedral and the Bazaar, de Eric Raymond), mesmo sem conhecimento técnico. Outra possibilidade é através de ajuda na documentação - melhorar uma documentação incompleta ou traduzir para outras línguas. Porém, apesar de não exigir conhecimentos específicos, exige tempo, o que nem sempre as pessoas têm disponível.

No caso do Firefox, há uma outra forma de contribuir para o projeto, que não exige qualquer conhecimento específico. É através do Test Pilot, uma extensão que, ao ser instalada, exibe uma lista de estudos sendo conduzidos pela Mozilla. Sempre que surgir um novo estudo, você poderá ver os detalhes dele e optar por participar ou não. O estudo que acontece com mais frequencia é o “A Week in the Life of a Browser”, onde, caso você aceite participar, durante uma semana o Test Pilot monitorará informações sobre o seu uso do browser, como memória utilizada, número de abas abertas simultaneamente, número de downloads e de bookmarks - ou seja, nenhuma informação sensível do usuário é coletada. No final do período do estudo, esses dados são enviados para a Mozilla, mas antes você pode ver exatamente que informações serão enviadas através de gráficos como esse:

Test Pilot

Alguns estudos são pesquisas sobre usabilidade e funcionalidades específicas, como mecanismos de busca e uso de bookmarks e dos botões na toolbar. Para ver os estudos já realizados, acesse a página de test cases. Para participar, basta instalar a extensão.


A classe Time do Ruby é usada, como esperado, para representar uma data e hora. Existem várias formas de criar uma nova instância, a mais óbvia é usando Time.new (ou Time.now), que cria uma nova instância com a data e hora atuais:

irb(main):007:0> Time.new
=> Wed Feb 09 13:23:52 -0200 2011
irb(main):008:0> Time.now
=> Wed Feb 09 13:23:53 -0200 2011

Também é possível criar uma instância usando métodos como Time.at(time), que recebe um timestamp como parâmetro, Time.local(year, month, day, hour, min, sec_with_frac) e outros. Também há um construtor que recebe como parâmetro uma string representando a data:

irb(main):001:0> Time.new('2011-01-01')
=> Sat Jan 01 00:00:00 -0200 2011

Eu havia escrito um código que usava esse construtor no pidgin-logs-compressor, mas quando testei no JRuby 1.5.5, recebi uma exceção “ArgumentError: wrong number of arguments (1 for 0)”. Achei que fosse algum bug do JRuby, e realmente havia esse bug na versão que eu usava, mas já estava corrigido no JRuby 1.6RC1. Atualizei para esta versão, mas o erro continuou. Descobri que o erro que eu estava cometendo era relacionado com a versão do Ruby, e não do JRuby. Esse construtor com parâmetros é aceito no Ruby 1.9, mas não no 1.8.7, que é a versão usada por padrão pelo JRuby. Para fazer com que ele utilize a versão 1.9, basta acrescentar o parâmetro --1.9 na linha de comando:

jruby --1.9 -e 'puts Time.new("2011-02-16")'

Para manter compatibilidade com versões anteriores, é necessário usar algum dos outros métodos, como eu optei por fazer no pidgin-logs-compressor.

Para um overview de algumas novidades do Ruby 1.9: New Ruby 1.9 Features, Tips & Tricks.