quarta-feira, 5 de agosto de 2009

Enviar parâmetros para um partial

Essa é uma dica simples, mas que tem sua utilidade.

O método render :partial recebe um hash com o nome locals. O conteúdo desse hash é disponibilizado dentro do partial como variáveis locais.

Por exemplo:

<%= render :partial => 'example', :locals => {:name => 'Bruno'} %>

Nesse caso estou passando uma variável name com o valor "Bruno" para o partial example.

Mas qual é a utilidade disso?

Vou dar um exemplo prático que aconteceu comigo esses dias.

Minha aplicação tem um model User e, ao criar as views para manipular esse model, percebi que o formulário da view new e o da view edit eram idênticos. Então nada melhor do que colocar esse conteúdo dentro de um partial e reaproveitar o código ao bom e velho estilo DRY (Don't Repeat Yourself).

Fiz isso e meu partial ficou próximo ao do exemplo (clique na imagem para ampliar):



A partir daí eu renderizei esse partial nas duas views (new e edit).

Só que depois de um tempo eu resolvi retirar alguns campos da view de cadastramento (new) para poder tornar o cadastro mais rápido, atraindo mais usuários. Para isso eu removi os campos name e last_name.

Uma vez que agora as views new e edit são diferentes, eu só posso manter no partial o que é comum às duas, então mantive no partial apenas a parte interna do formulário, com exceção dos campos mencionados. O partial ficou assim:



E para renderizar esse partial, eu deixei a view como de costume (render :partial):



O problema é que, o objeto "f" que é passado ao bloco do helper form_for está sendo criado na view e não existe dentro do partial. Quando o partial tentar acessar o "f" retornará um erro dizendo "undefined local variable or method `f'".

Para resolver esse problema, eu vou enviar para o partial o objeto "f", para que ele exista em seu escopo e solucione o meu problema.

Resultado (linha 4):



Problema resolvido!

É isso aí pessoal, espero que a dica ajude alguém que esteja com esse problema, ou pelo menos incentive o reaproveitamento de código nas views.

Abraços e até o próximo post!

4 comentários:

Nelson disse...

Fiz bastante disso num projeto passado. Acredito ser a forma "normal" de passar variáveis para o partial, o rails que aproveita pra setar variáveis quando escrevemos:

render :partial => @user
render :partial => 'user', :object => @user
render :partial => 'user', :collection => @users

mas se você for usar algo diferente do objeto tem que ser :locals => {}

Bruno Grasselli disse...

Nelson,

Obrigado por complementar o post com essas informações. Eu mesmo não sabia dessa possibilidade de passar um objeto pra renderizar um partial.

Vou usar essa abordagem ainda nesse projeto.

Abraços.

Sequelanet disse...

caracaaaa...
não entendo nada de programação D:
Abraços

Battisti disse...

Valeu pela ajuda