label e label_tag helpers do Rails
Me lembro que enquanto aprendia Rails me questionava por que usar helpers para tarefas comuns como criar links ou divs… e logo percebi que era uma excelente maneira de ser produtivo ao escrever as views do projeto.
Por exemplo é muito melhor escrever:
<%= stylesheet_link_tag "application","login","common" %>
do que:
<link href="/stylesheets/app.css" media="screen" rel="stylesheet" type="text/css">
<link href="/stylesheets/login.css" media="screen" rel="stylesheet" type="text/css">
<link href="/stylesheets/common.css" media="screen" rel="stylesheet" type="text/css">
Por este motivo devemos conhecer bem os helpers do Rails, e um em especial é pouco utilizado ou não utilizado da forma correta. Hoje enquanto alterava a UI de um projeto que tenho trabalho percebi que não tenho usado os helpers label e label_tag da forma correta, especialmente no caso dos radio buttons.
A função do label do html é prover uma forma de você associar um texto (rótulo) a um campo de formulário. E a sintaxe para isto é:
<input type="radio" value="selected" name="available" id="available">
<label for="available">Disponível</label>
ou ainda:
<label for="available">
<input type="radio" value="selected" name="available" id="available">Disponível
</label>
No caso do radio e checkbox, desta forma você consegue marcar a opção apenas clicando no label ( o que aumenta a área ‘clicável’).
A primeira forma é a mais indicada e no Rails podemos obter o mesmo resultado assim:
<%= f.radio_button :available, "true" %> <%= f.label :available, "Disponível" %>
Porém, e quando temos dois radios (o que é o normal) como vamos associar o label? O que muitos não sabem é que no caso do radio quando temos dois campos como mesmo nome (estou me referindo a radio1) o Rails concatena o valor do radio ao name.
E outro detalhe que muita gente não sabe é que o label não precisa receber exatamente o nome do radio ou input á quem está associado. Então a boa prática é que quando tiver dois radios faça como abaixo:
<%= f.radio_button :available, "false"%>
<%= f.label "available_false", "Fora de estoque" %>
<br/>
<%= f.radio_button : available, "true"%>
<%= f.label "available_true", "Disponível" %>
Desta forma o rails vai criar o ID dos radios como radio1_false e radio1_true e você poderá associa-los ao label e assim permitir ao usuário que quando clique no texto do radio ele seja marcado e não apenas clicando na bolinha.
Observação
no caso acima como estou usando label e não label_tag é necessário que eu esteja dentro de um form_for ou passe como primeiro parâmetro o objeto á quem pertence o radio. Por exemplo, se este form é para um objeto produto este objeto é representado como o f. na frente do f.radio_button (também poderia usar radio_button(f, :radio_1, “false”) e assim o rails criará o id do html como abaixo:
<input id="product_available_true" name="product[available]" type="radio" value="true">
E desta forma o Rails concatena o nome do objeto no id tanto em radio_button quanto em label.
Dica importante
Outra dica muito importante. Se tiver usando o radio para valores boolean para ser gravado no banco de dados, use sempre em string “true” ou “false” e não as pseudo variáveis true e false. Desta forma o Rails vai criar o id como mostrado acima, concatenando true e false ao final do ID e permitindo o uso label corretamente.
Por baixo dos panos
Param quem estiver se perguntando como Rails faz a conversão da string “true”, “1”, “0”, “false” e etc para os devidos tipos boolean então veja o código fonte do método value_to_boolean