{"id":833,"date":"2010-03-19T09:16:16","date_gmt":"2010-03-19T12:16:16","guid":{"rendered":"http:\/\/blog.plataformatec.com.br\/?p=833"},"modified":"2010-04-22T14:55:56","modified_gmt":"2010-04-22T17:55:56","slug":"mostre-seus-models-baby","status":"publish","type":"post","link":"https:\/\/blog.plataformatec.com.br\/2010\/03\/mostre-seus-models-baby\/","title":{"rendered":"Mostre seus models baby!"},"content":{"rendered":"
Ultimamente temos trabalhado em alguns projetos que necessitaram de v\u00e1rios CRUDs na administra\u00e7\u00e3o como p\u00e1ginas mostrando listas de atributos. E com passar do tempo, est\u00e1vamos ficando entediados de tanto copiar e colar c\u00f3digo como este para cada atributo em nossas p\u00e1ginas:<\/p>\n
\r\n\r\n Name<\/strong>
\r\n <%= @person.name %>\r\n<\/p>\r\n<\/pre>\nN\u00f3s j\u00e1 tinhamos criado um helper para fazer o trabalho para n\u00f3s, mas copiar este helper de um projeto para outro n\u00e3o \u00e9 DRY. Ent\u00e3o decidimos criar uma nova gem, chamada ShowFor<\/a>.<\/p>\nShowFor<\/a> \u00e9 uma DSL para auxili\u00e1-lo a mostrar uma lista de atributos, usando I18n, perfeito para p\u00e1ginas de visualiza\u00e7\u00e3o em interfaces CRUDs. Ele permite que voc\u00ea substitua duplica\u00e7\u00e3o de c\u00f3digo\/html em suas views usando uma sintaxe mais atraente. Vejamos o que podemos fazer!<\/p>\nAtributos<\/h3>\n
Vamos imaginar que temos um model Person, que possui os atributos first_name, last_name, age, photo, e confirmed. As linhas abaixo criam uma lista de valores para um registro espec\u00edfico:<\/p>\n
\r\n<% show_for @person do |p| %>\r\n <%= p.attribute :first_name %>\r\n <%= p.attribute :last_name %>\r\n <%= p.attribute :confirmed? %>\r\n <%= p.attribute :created_at, :format => :short %>\r\n <%= p.attribute :age, :if_blank => \"No age\" %>\r\n\r\n <% p.attribute :photo do %>\r\n <%= image_tag(@person.photo_url) %>\r\n <% end %>\r\n<% end %>\r\n<\/pre>\nE este \u00e9 o c\u00f3digo HTML que voc\u00ea tem como resultado:<\/p>\n
\r\n\r\n First name<\/strong>
Carlos<\/p>\r\n Last name<\/strong>
Antonio<\/p>\r\n Confirmed?<\/strong>
Yes<\/p>\r\n Created at<\/strong>
08 Mar 11:30<\/p>\r\n Age<\/strong>
24<\/p>\r\n Photo<\/strong>
\r\n \r\n <\/p>\r\n<\/div>\r\n<\/pre>\nComo se pode ver, voc\u00ea ter\u00e1 uma marca\u00e7\u00e3o HTML padr\u00e3o, com classes e ids para ajud\u00e1-lo no design com CSS. E caso tenha notado, estamos usando op\u00e7\u00f5es extras em alguns atributos, vamos dar uma olhada em algumas delas:<\/p>\n
\n:format<\/code> permite que voc\u00ea defina um formato a ser usando com I18n, somente para atributos date\/time, como voc\u00ea usaria com o helper l<\/code>.<\/li>\n:if_blank<\/code> define o que ser\u00e1 mostrado caso o atributo esteja em branco. Pode ter um valor padr\u00e3o via I18n.<\/li>\ndo...end<\/code>: usando blocos voc\u00ea mesmo pode manusear o conte\u00fado para o atributo espec\u00edfico, como fizemos no exemplo para o atributo photo<\/code>.<\/li>\n<\/ul>\nAtributos booleanos, como nosso :confirmed<\/code>, tamb\u00e9m possuem um valor padr\u00e3o para true<\/code> e false<\/code>, e podem ser configurados atrav\u00e9s de I18n. Se voc\u00ea deseja mostrar “Sim” e “N\u00e3o” no lugar de “Yes” e “No” respectivamente, s\u00f3 precisa mudar seu arquivo I18n. Voc\u00ea tamb\u00e9m pode passar a op\u00e7\u00e3o :escape<\/code> para n\u00e3o escapar o conte\u00fado (true<\/code> por padr\u00e3o).<\/p>\nAssocia\u00e7\u00f5es<\/h3>\n
ShowFor<\/a> tamb\u00e9m funciona com associa\u00e7\u00f5es. Por exemplo, podemos adicionar que nosso Person agora pertence a um model City com um atributo nome, e que tamb\u00e9m possui e pertence a muitas Tags. Para gerenciar o primeiro, podemos fazer:<\/p>\n\r\n<%= p.association :city %>\r\n<\/pre>\nShowFor<\/a> ir\u00e1 adivinhar o atributo correto para mostrar procurando todas as possibilidades configuradas em ShowFor.association_methods<\/code> e neste caso escolhendo :name. Mas \u00e9 claro, voc\u00ea pode modificar isso se precisar:<\/p>\n\r\n<%= p.association :city, :using => :full_name %>\r\n<%= p.attribute :full_name, :in => :city %>\r\n<\/pre>\nAmbas as possibilidades acima ter\u00e3o a mesma sa\u00edda, apenas escolha a que voc\u00ea mais gostar.<\/p>\n
Manusear cole\u00e7\u00f5es \u00e9 t\u00e3o f\u00e1cil quanto associa\u00e7\u00f5es belongs_to. Voc\u00ea simplesmente passa a associa\u00e7\u00e3o para ShowFor<\/a> e ele ir\u00e1 saber se \u00e9 uma cole\u00e7\u00e3o ou n\u00e3o, gerando uma lista de elementos usando tags ul<\/code> e li<\/code>.<\/p>\n\r\n<%= p.association :tags %>\r\n<\/pre>\nEntretando, se voc\u00ea quiser renderizar a cole\u00e7\u00e3o inline, pode usar as op\u00e7\u00f5es :to_sentence e :join:<\/p>\n
\r\n<%= p.association :tags, :to_sentence => true %>\r\n<%= p.association :tags, :join => ',' %>\r\n<\/pre>\nTamb\u00e9m \u00e9 poss\u00edvel passar um bloco para a cole\u00e7\u00e3o. O ShowFor<\/a> criar\u00e1 a tag wrapper (ul<\/code> por padr\u00e3o nesse caso) e retornar\u00e1 cada elemento da cole\u00e7\u00e3o para voc\u00ea gerenci\u00e1-lo:<\/p>\n\r\n<% a.association :tags do |tag| %>\r\n
- <%= link_to tag.name, tag %><\/li>\r\n<% end %>\r\n<\/pre>\n
Labels<\/h3>\n
Voc\u00ea deve ter percebido que o ShowFor<\/a> possui um label padr\u00e3o usando a tag strong<\/code>. Ele tamb\u00e9m exp\u00f5e a voc\u00ea o m\u00e9todo label<\/code> como um helper, para que possa us\u00e1-lo quando desejar:<\/p>\n\r\n <%= p.label :first_name %>\r\n <%= p.label :age, :id => 'person_age' %>\r\n\r\n First name<\/strong>\r\n Age<\/strong>\r\n<\/pre>\nInstala\u00e7\u00e3o<\/h3>\n
O ShowFor<\/a>, em sua vers\u00e3o 0.2.0, j\u00e1 \u00e9 compat\u00edvel com o Rails 3. Voc\u00ea pode seguir as instru\u00e7\u00f5es no README<\/a> para instal\u00e1-lo.<\/p>\nSe voc\u00ea est\u00e1 usando o Rails 2.3.x, pode dar uma olhada no branch 0.1<\/a>, e seguir as instru\u00e7\u00f5es no README<\/a> deste branch para utiliz\u00e1-lo.<\/p>\nE ap\u00f3s a instala\u00e7\u00e3o, n\u00e3o se esque\u00e7a de executar o generator e dar uma olhada no initializer gerado, que permite que voc\u00ea configure v\u00e1rias partes do ShowFor<\/a>.<\/p>\n\r\nscript\/generate show_for_install\r\n<\/pre>\nFechando<\/h3>\n
ShowFor<\/a> ajuda voc\u00ea a mostrar os atributos de seus objetos facilmente com uma marca\u00e7\u00e3o html padr\u00e3o, e pode ser totalmente configurado para atender sua necessidade. Ele tem nos ajudado em todos os projetos, e esperamos que ele possa ajud\u00e1-lo tamb\u00e9m. Se voc\u00ea tiver alguma d\u00favida, por favor d\u00ea uma olhada no README<\/a>, existem muitos exemplos e documenta\u00e7\u00e3o l\u00e1.<\/p>\nE voc\u00ea? Possui algum helper que usa todos os dias e que poderia ser transformado em um plugin\/gem? N\u00e3o hesite em fazer isto, ficaremos contentes em ver seu trabalho!<\/p>\n
Divirta-se!<\/p>\n","protected":false},"excerpt":{"rendered":"
Ultimamente temos trabalhado em alguns projetos que necessitaram de v\u00e1rios CRUDs na administra\u00e7\u00e3o como p\u00e1ginas mostrando listas de atributos. E com passar do tempo, est\u00e1vamos ficando entediados de tanto copiar e colar c\u00f3digo como este para cada atributo em nossas p\u00e1ginas: Name N\u00f3s j\u00e1 tinhamos criado um helper para fazer o trabalho para n\u00f3s, mas … \u00bb<\/a><\/p>\n","protected":false},"author":7,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"ngg_post_thumbnail":0,"footnotes":""},"categories":[3],"tags":[],"aioseo_notices":[],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/posts\/833"}],"collection":[{"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/users\/7"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/comments?post=833"}],"version-history":[{"count":14,"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/posts\/833\/revisions"}],"predecessor-version":[{"id":908,"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/posts\/833\/revisions\/908"}],"wp:attachment":[{"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/media?parent=833"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/categories?post=833"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/tags?post=833"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}