Rails 3: Usando OpenStruct em formulários de busca
Fazer formulários que não tenha um Model diretamente associado sempre foi um problema no Rails. Isso se deve ao “Convention over configuration” e não vejo grandes problemas nisso, pois 90% dos formulários são para criação/edição de dados no Banco de Dados e, por conseqüência, utilizam um Model.
Mas e os outros 10%?
Vi um artigo no blog da Plataforma sobre como resolver esse problema, porém o código parou de funcionar com o Rails 3. Para descobrir o por que disso, fui investigar no código do Rails (a esse mundo OpenSource) e descobri que quando você inclui por exemplo um text_field é retornado um novo objeto da classe InstanceTag e executa o método to_input_field_tag.
Neste método to_input_field_tag, que está o problema. Passou-se a testar se na classe que está sendo chamado o form existe o método do text_field que queremos e nesse caso não existe, gerando um erro.
Para contornar isso é nessesário fazer um Monkey Patch na classe OpenStruct modificando o método respond_to?:
class OpenStruct
def respond_to?(symbol, include_private = false)
! ActiveRecord::Base.instance_methods.include? symbol.to_s
end
end
Assim, ele responderá a qualquer coisa menos ao aos métodos de instância que o ActiveRecord, evitando que nos passemos totalmente por um model, o que causaria outros problemas.
Além disso modifiquei o nome do helper, já que não utilizava isso apenas para buscas, e primeiro é verificado se uma variável de instância com o nome do objeto existe (@contacts por exemplo) e caso não exista é buscado da variável params:
require 'ostruct'
module OpenFormHelper
def open_form_for(object_name, options={}, &block)
options[:html] = {:method => :get}.update(options[:html] || {})
options[:as] = object_name
object = OpenStruct.new(instance_variable_get("@#{object_name}") || params[object_name])
form_for(object, options, &block)
end
end
Fiz a modificação da variável pois em algumas buscas queria que algumas opções viessem marcadas por padrão, ou seja teria que adicioná-las a uma variável e escrever no params não é recomendável.
Quanto a utilização, veja lá o artigo do Vinícius lá no blog da plataforma que tem exemplos de utilização.
Lendo o código do Rails
Uma dica final que eu gostaria de deixar é que quando problemas como esse ocorrem é a melhor hora para investigar o código do Rails e tentar descobrir o que está acontecendo, ficando muito mais fácil entendermos como o Framework funciona.


Tenho andado com os meu queixo dolorido nos últimos dias. Há um mês estou fazendo o curso de
Outra grande vantagem do Rails, é o Ruby. Isso mesmo, a linguagem utilizada no framework é muito boa. É legível, padronizada e muito poderosa. Eu trabalho com PHP fazem 4 anos e não quero cuspir no prato que comi (e ainda como), mas PHP é muito desorganizada.
…e também a pen drives, card drives, camisetas geeks, livros e mais! O BR-Linux e o Efetividade lançaram uma campanha para ajudar a Wikimedia Foundation e outros mantenedores de projetos que usamos no dia-a-dia on-line. Se você puder doar diretamente, ou contribuir de outra forma, são sempre melhores opções. Mas se não puder, veja as regras da promoção e participe - quanto mais divulgação, maior será a doação do BR-Linux e do Efetividade, e você ainda concorre a diversos brindes!