Paperclip, reais vantagens
Upload de arquivos em Rails é absurdamente simples, e um dos motivos que me fez amar este framework a primeira vista. Isso graças a alguns plugins que tornam o upload muito simples.
!https://s3.amazonaws.com/objetiva/blog/2009/1/16/paperclip.jpg!
Mas se attachment_fu é tão bom, então porque usar paperclip? Ultimamente comecei a usar o paperclip em alguns projetos… e de fato ele consegue ser mais simples de configurar que o attachment_fu. Mas muito do que se fala por aí não passa de falta de conhecimento no attachment_fu, pois praticamente quase todos os recurso do paperclip estão presentes no attachment_fu.
Então quais são as reais vantangens?
Muito tem se falado do plugin paperclip para upload de imagens em projetos Rails. Me lembro bem quando estava começando a aprender Rails, fui direto para a parte de upload que era uma coisa que me dava bastante dor de cabeça em PHP ( upload decente não é um send_file e pronto, você precisa de redimensionamento, thumbnails, validação e etc ) e fiquei surpreso que com apenas umas 2 ou 3 linhas de código em meu model e o acréscimo de alguns campos no DB eu poderia fazer um upload realmente robusto e de forma absurdamente simples.
Para isso eu estava usando o attachment_fu e continuo usando em alguns projetos até hoje. É um plugin muito bom e utiliza o ImageMagick para trabalhar com as imagens( se o upload for uma imagem) que vão ser subidas…. diante do ImageMagick o attachment_fu aceita algumas opções para intermediar o acesso ao ImageMagick, opções como RMagick, ImageScience ou MiniMagick.
!https://s3.amazonaws.com/objetiva/blog/2009/1/16/paperclip.jpg!
Mas se attachment_fu é tão bom, então porque usar paperclip? Ultimamente comecei a usar o paperclip em alguns projetos… e de fato ele consegue ser mais simples de configurar que o attachment_fu. Mas muito do que se fala por aí não passa de falta de conhecimento no attachment_fu, pois praticamente quase todos os recurso do paperclip estão presentes no attachment_fu.
Em ambos você pode usar um model para armazenar as imagens, ou ter as imagens na mesma tabela ( por exemplo user, já ter seu avatar na tabela user), ambos fazem redimensionamento( através do imagemagick), ambos podem colocar arquivos fora da pasta public, ambos tratam seu upload como um campo simples do seu model ( basta excluir o registro e a imagem também será excluída, basta passar um novo arquivo em um campo file_field com o name do seu atributo e ele será atualizado), ambos podem fazer validações em seu model. Outra coisa que ambos podem fazer sem muito trabalho é usar o Amazon S3 para guardar os arquivos.
h3. Por que o PaperClip é mais fácil de configurar?
Os passos para um upload com Attachment_fu e Paperclip são bem parecidos, mas o que torna o paperclip mais simples é um generator que ele cria. Esse generator não faz nada mais que criar um migration para acrescentar os campos de upload no banco de dados. No attachment_fu também fazemos isso, mas não temos um generator então precisamos criar a migration na mão (mas não é nada de mais).
h3. Mas então, quais são as reais vantagens do Paperclip ?
Do meu ponto de vista, se você já possui um projeto com attachment_fu não faz o menor sentido mudar para paperclip. Mas se você irá começar um novo projeto o Paperclip pode ser mais interessante.
Paperclip deixa menos espaço para problemas com bibliotecas como Rmagick ou ImageScience pois ele usa direto o ImageMagick ( mas isto pode gerar problemas se você usa passenger em modo de desenvolvimento, vamos falar mais sobre isso). E desta forma ele diminui uma configuração, ficando mais simples de usar.
Paperclip por padrão permiti que você defina url e path, desta forma a url de acesso do arquivo será diferente do caminho do arquivo no servidor. Este feature o torna bem útil em projetos onde você queira fazer o upload do arquivo para uma pasta fora da public e enviar o arquivo por send_file ou x_send_file. Um exemplo de projeto desses, seria um site adulto onde apenas membros pagantes possam ver as fotos ( se estiver dentro da pasta public, ele será conteúdo estático e será servido direto pelo servidor web e não passará por um autenticação da sua app Rails), ou um projeto onde você armazene documentos dos usuários e não queira que todos tenham acesso aos documentos de todo mundo.
Outra vantagem do paperclip são suas validações. Pessoalmente acho a sintaxe das validações do paperclip muito mais claras que a do attachment_fu, mas isso é pessoal.
Mais um ponto para o paperclip são alguns rake tasks. Uma coisa infernal é quando voê já possui um projeto onde vários usuários enviaram imagens e você já tinha definido os tamanhos para o redimensionamento e thumbnails e agora você decide que as imagens devem ter um outro tamanho. O paperclip ataca neste ponto com as seguintes tasks:
<macro:code lang=“ruby”>
Cleans out invalid attachments.
rake paperclip:clean
Refreshes both metadata and thumbnails.
rake paperclip:refresh
Regenerates content_type/size metadata for a given CLASS (and optional ATTACHMENT).
rake paperclip:refresh:metadata
Regenerates thumbnails for a given CLASS (and optional ATTACHMENT).
rake paperclip:refresh:thumbnails </macro:code>
A primeria task permite apagar os anexos que inválidos. As outras 3 tasks servem extamente para o que eu tinha dito anteriormente.
rake paperclip:refresh
Atualiza tanto os dados armazenados na tabela do db quanto os arquivos mesmo no filesystem, isso de acordo com seus styles (tamanhos definidos para os arquivos) em seu model.
rake paperclip:refresh:metadata
Atualiza apenas os dados armazenados no banco de dados ( “xxxxx_file_name”, “xxxx_content_type”, “xxxx_file_size”, “xxxx_updated_at” )
rake paperclip:refresh:thumbnails
Atualiza os arquivos no filesystem de acordo com os styles pré-definidos no model.
h3. Conclusão
Paperclip e Attachment_fu são muito bons, mas Paperclip possui algumas vantagens que dependendo do seu projeto e necessidade justificam o uso ou até migrar para ele.
h3. Problemas com Passenger
Eu utilizo o Passenger em modo de desenvolvimento no meu Mac e observei que dependendo das configurações da sua máquina o passenger não conseguirá achar o ImageMagick dependendo de onde ele estiver instalado, e não fará o redimensionamento dos styles.
Para resolver isso existem algumas formas, mas o jeito mais fácil que encontrei foi criar um arquivo chamado paperclip.rb dentro da pasta config/initializers do seu projeto com o seguinte conteúdo:
<macro:code lang=“ruby”> Paperclip.options[:image_magick_path] = ‘/opt/local/bin/’ if RAILS_ENV == “development” </macro:code>
Desta forma você está definindo o caminho do image_magick manualmente.