O plugin paperClip do Ruby on Rails é muito bacana, agiliza muito a vida, com ele é possível fazer upload de imagens e já gerar várias dimensões da imagem.
Vou explicar como instalar e como usar.
Instalação:
Faça o download do paperClip: http://github.com/tarballs/thoughtbot-paperclip-18c0246c11c51dafa77b6367ddaf730684d0e752.zip
Descompacte o arquivo e renomei o diretório extraído para paperclip.
Coloque esse diretório dentro de seu_projeto/vendor/plugins/paperclip.
Você vai precisar do imageMagick, através dele o paperClip faz o resize nas imagens. Para instalar no Ubuntu 8.04 faça:
1
| sudo apt-get install imagemagick |
Configuração:
Para o paperClip funcionar você vai precisar que exista 4 novas colunas na sua tabela são elas: image_file_name, image_content_type, image_file_size, image_updated_at.
Esse nome image_… pode ser qualquer outra coisa por exemplo: avatar_…, foto_…
Seguindo essa ideia você poderia ter um migrate mais ou menos assim:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| class CreateTournaments < ActiveRecord::Migration
def self.up
create_table :tournaments do |t|
t.column :name, :string, :limit => 100, :null => false
t.column :description, :text, :null => true
t.column :image_file_name, :string
t.column :image_content_type, :string
t.column :image_file_size, :integer
t.column :image_updated_at, :timestamp
t.column :is_active, :boolean, :null => false, :default => false
t.column :start_date, :date, :null => false
t.column :end_date, :date, :null => false
t.column :created_at, :timestamp, :null => false
t.column :updated_at, :timestamp, :null => false
end
end
def self.down
drop_table :tournaments
end
end |
Agora é necessário informar o seu model que existirá anexos e que formatos são aceitos:
1
2
3
4
5
6
7
8
9
10
| class Tournament < ActiveRecord::Base
has_attached_file :image,
:styles => {:large => '600x600>', :medium => '300x300>', :small => '150x150>', :thumb => '50x50>'},
:path => ":rails_root/public/images/:class/:id/:style_:basename.:extension",
:url => "/images/:class/:id/:style_:basename.:extension"
validates_uniqueness_of :name
validates_presence_of :name, :start_date, :end_date
validates_attachment_content_type :image, :content_type => ['image/jpeg', 'image/png', 'image/gif']
end |
O interessante da linha abaixo, é que posso definir todos os tamanhos de imagens que desejo gerar em cima da imagem original, nesse trecho de código eu também alterei o path de armazenamento das imagens, fiz as imagens ficarem no diretório public_html/images/tournaments/id_do_banco_de_dados/imagens_em_diversas_dimensões:
1
2
3
4
| has_attached_file :image,
:styles => {:large => '600x600>', :medium => '300x300>', :small => '150x150>', :thumb => '50x50>'},
:path => ":rails_root/public/images/:class/:id/:style_:basename.:extension",
:url => "/images/:class/:id/:style_:basename.:extension" |
A linha seguinte informa os tipos de mime types aceitos:
1
| validates_attachment_content_type :image, :content_type => ['image/jpeg', 'image/png', 'image/gif'] |
Agora você precisa definir que o seu formulário de cadastro trabalha com multipart, para enviar dados binários:
1
2
3
4
| <% form_for :tournament, @tournament, :url => { :action => 'create' }, :html => { :multipart => true } do |form| %>
<%= render :partial => 'form', :locals => { :form => form } %>
<div class="submit"><%= submit_tag "Criar" %></div>
<% end %> |
No código acima eu chamo o partial _form.rhtml, segue o seu conteúdo abaixo:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| <%= error_messages_for 'tournament' %>
<!--[form:tournament]-->
<p><label for="tournament_name">Nome</label>
<%= form.text_field :name %></p>
<p><label for="tournament_description">Descrição</label>
<%= form.text_area :description %></p>
<p><label for="tournament_image">Imagem</label>
<%= form.file_field :image %></p>
<p><label for="tournament_is_active">Ativo</label>
<%= form.check_box :is_active %>
<p><label for="tournament_start_date">Data de início</label>
<%= form.date_select(:start_date, :order => [:day, :month, :year], :use_month_numbers => true) %></p>
<p><label for="tournament_end_date">Data de término</label>
<%= form.date_select(:end_date, :order => [:day, :month, :year], :use_month_numbers => true) %></p>
<!--[eoform:tournament]--> |
Nesse partial _form.rhtml é declarado o campo para upload da imagem:
1
| <%= form.file_field :image %> |
Perceba que na tabela do banco de dados não existe a coluna chamada image, mas sim aquelas 4 que criei no migrate. Aqui que entra a mágica do paperClip juntamente com o model, ele consegue fazer o upload da imagem e definir os valores para os 4 campos no model.
Para exibir as imagens e suas diversas proporções use:
1
2
3
4
| <%= image_tag @tournament.image.url(:thumb) %>
<%= image_tag @tournament.image.url(:small) %>
<%= image_tag @tournament.image.url(:medium) %>
<%= image_tag @tournament.image.url(:large) %> |
Pronto! Depois de pegar o jeito com o paperClip você vai dar risada a toa. ;-)
Se você gostou desse texto e acha que ajudou você, me recomende:
.