Em aplicações Rails, ou qualquer outra aplicação web na verdade, muitas vezes é necessário gerar dados em diferentes formatos, formatos que não são HTML, CSS, Javascript ou qualquer outro formato padrão web, e se você esta utilizando os Responders do Rails 3+ tem uma forma bem fácil de gerar outros formatos de texto.
Na verdade duas formas bem simples, a primeira e mais óbvia é criar uma view utilizando alguma das template engines suportadas, por exemplo, neste caso, para gerar um arquivo CSV utilizando esta abordagem, seria necessário fazer o seguinte …
No controlador, na linha onde se encontra o “respond_to” adicione :csv como no exemplo:
respond_to :html, :js, :csv
Na ação do controlador utilize normalmente o “responds_with” e crie um template para renderizar o CSV, por exemplo para a ação index de um controlador chamado produtos:
1 2 3 4 | id, name, description <% @products.each do |prod| %> <%= prod.id %>,<%= prod.name %>,<%= prod.description %> <% end %> |
Mas se quiser uma forma mais genérica de fazer algo parecido, pode fazer o seguinte …
No arquivo ‘config/initializers/mime_types.rb’ adicione a linha abaixo:
Mime::Type.register "text/csv", :csv
Depois crie outro arquivo no diretório de initializers ou qualquer arquivo que seja carregado pelo rails, e adicione o método “to_csv” onde você quiser utiliza-lo, no exemplo abaixo eu adicionei na classe “Array”.
1 2 3 4 5 6 7 8 | class Array def to_csv(options = {}) map do |it| attrs = options[:attributes] || it.attribute_names attrs.map{|attr| it.send attr.to_sym }.join(',') end.join("\n") end end |
Uma observação importante é que este código vai colocar todo o CSV em memória antes de enviar para o cliente, então se você pode ter alguma lista muito grande, esta não é a melhor opção, mas o código ficou bem clean na minha opinião.
Se a lista for muito grande, pensando apenas em utilização de recursos do servidor, eu carregaria os dados do banco em lotes em vez de carregar a lista toda de uma vez, armazenaria a lista em disco e enviaria o arquivo utilizando “send_file”, mas claro que para pensar em uma solução destas precisamos levar em conta diversos fatores.
Acho que vou colocar aqui um exemplo gerando PDF, o que acham? Derepente até com comentários sobre as formas de gerar PDF em Ruby que eu já usei …
Falando nisto, vocês já viram os guias de referência rápida que estou publicando no blog? Se ainda não viu, de uma passada la para baixar os PDFs, sugestões são bem vindas.