
Introdução 🙂
É muito comum você precisar fazer o upload de fotos ou múltiplos anexos em suas aplicações Web e o Rails fornece Gems que facilitam muito esse processo.
O que vamos aprender?
Nesse tutorial nós vamos usar o CarrierWave + Bootstrap + Simple Form para criar uma página que servirá para fazer o Upload de uma foto e de múltiplos anexos, vamos aprender também como limitar o upload de arquivos baseado na extensão.
INGREDIENTES
- Ruby 2.3.1
- Rails 5
- PostgreSQL
- CarrierWave (Gem)
- Mini Magick (Gem)
- Bootstrap
- Simple Form (Gem)
Objetivos
Criar um Form para fazer o upload de uma foto e de múltiplos anexos simulando uma página de perfil de um usuário (necessidade comum nos Web Apps).
Passo a Passo
- Criar a estrutura do nosso Projeto
- Criar os Uploaders e personalizá-los pra limitar o upload por tipo de extensão e separar por vários tamanhos de imagem.
- Personalizar nossos Views para subir os arquivos e depois mostrá-los
Mãos à Obra \o/
Parte 1 – Criando a estrutura do Projeto
Primeiro vamos criar nosso projeto Rails, instalar as dependências, incluir as Gems e criar o scaffold User para guardar os dados do usuário.
- Para começar, rode no seu console o comando para gerar o projeto:
1rails new form_uploader --database=postgresql - Nós precisamos instalar o imagemagick no sistema:
- Em sistemas linux que usem o apt-get, rode:
1sudo apt-get install imagemagick - No Mac:
1sudo brew install imagemagick
- Em sistemas linux que usem o apt-get, rode:
- No seu Gemfile, adicione as seguintes Gems:
1234gem 'carrierwave', github: 'carrierwaveuploader/carrierwave'gem 'bootstrap', '~> 4.0.0.alpha5'gem 'simple_form'gem 'mini_magick', '~> 4.3' - Vamos rodar o Bundle para instalar as Gems:
1bundle - Nós estamos usando nesse tutorial o PostgreSQL como banco de dados para poder usar o tipo “json” do banco de dados que será útil para conectar os múltiplos anexos facilmente, então configure as credenciais do seu banco de dados no arquivo ‘config/database.yml’.
- Vamos instalar o Bootstrap para dar uma aparência melhor à nossa aplicação:
- Substitua o conteúdo do arquivo ‘app/assets/stylesheets/application.css’ pelo seguinte código:
1@import "bootstrap";
Seu arquivo deve ficar dessa maneira:
- Renomeie o arquivo app/assets/stylesheets/application.css’ para app/assets/stylesheets/application.scss’
- Adicione no arquivo ‘app/assets/javascripts/application.js’ o seguinte código após a linha //= require jquery:
1//= require bootstrap-sprockets
Seu código deve ficar como a baixo:
- Substitua o conteúdo do arquivo ‘app/assets/stylesheets/application.css’ pelo seguinte código:
- Vamos instalar agora o Simple Form passando o parâmetro do bootstrap para que nosso form já seja gerado responsivo:
1rails generate simple_form:install --bootstrap
- Agora vamos criar o Scaffold, rode no console:
1rails g scaffold User first_name:string last_name:string email:string about:text - Crie o banco de dados e rode as migrations, no console rode:
12rake db:createrake db:migrate - Acesse seu projeto no browser http://localhost:3000/users e veja seu scaffold criado.
Pronto \o/, nosso projeto foi criado, agora vamos criar os Uploaders.
Parte 2 – Criar os Uploaders
Agora nós vamos criar dois perfis de Uploaders, incluí-los no User e customizá-los.
- Vamos criar o perfil para nossas imagens, rode:
1rails generate uploader Avatar - Agora inclua o avatar no nosso model User:
1rails g migration add_avatar_to_users avatar:string - Agora vamos configurar o Uploader Avatar para impedir que arquivos que não sejam jpg, gif ou png sejam aceitos pelo servidor, no arquivo ‘app/uploaders/avatar_upload.rb’ substitua o conteúdo por esse código:
123456789101112131415161718192021222324252627282930313233class AvatarUploader < CarrierWave::Uploader::Base# Adiciona o MiniMagick para permitir o redimensionamento das imagensinclude CarrierWave::MiniMagickstorage :file# Local onde será guardado as imagensdef store_dir"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"end## Tamanhos que o CarrierWave vai salvar as imagens# Thumbversion :thumb doprocess resize_to_fit: [50, 50]end# Mediumversion :medium doprocess resize_to_fit: [150, 150]end# Bigversion :big doprocess resize_to_fit: [300, 300]end# Tipos de extensão aceitasdef extension_whitelist%w(jpg jpeg gif png)endend - Vamos criar o perfil para nossos anexos:
1rails generate uploader Document - Inclua os documents (anexos) no nosso model User, para isto rode:
1rails g migration add_documents_to_users documents:json - Agora vamos configurar o Uploader Documents, no arquivo ‘app/uploaders/document_upload.rb’ substitua o conteúdo por esse código:
1234567class DocumentUploader < CarrierWave::Uploader::Basestorage :filedef store_dir"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"endend - Vamos adicionar ao app/model/user.rb à conexão com nossos uploaders, no arquivo inclua:
12mount_uploader :avatar, AvatarUploadermount_uploaders :documents, DocumentUploader - Vamos rodar as migrations:
1rake db:migrate - Inclua no arquivo ‘config/envoriment.rb’ o seguinte código:
1require 'carrierwave/orm/activerecord'
Seu código deve ficar assim:
Parte 3 – Personalizar as Views para subir a foto e os múltiplos anexos
Finalmente vamos editar nossas Views para poder fazer o Upload da foto e dos múltiplos anexos ao nosso projeto.
- Vamos adicionar ao form que foi gerado no scaffold os campos de photo e documentos, no file ‘app/views/users/_form.html.erb’ substitua o código por:
1234567891011121314151617181920<%= simple_form_for(@user) do |f| %><%= f.error_notification %><div class="form-inputs"><%= f.input :first_name %><%= f.input :last_name %><%= f.input :email %><%= f.input :about %><%= f.label 'Photo' %><%= f.file_field :avatar %><br/><%= f.label 'Documentos' %><%= f.file_field :documents, multiple: true %></div><br /><div class="form-actions"><%= f.button :submit %></div><% end %> - Edite seu User Controller (‘app/controllers/user_controller.rb’) para receber seus arquivos, para fazer isto altere seu método users_params para que ele fique da seguinte maneira:
123def user_paramsparams.require(:user).permit(:first_name, :last_name, :email, :about, :avatar, {documents: []})end - Agora vamos incluir na view app/views/user/show.html.erb as tags rails para mostrar o avatar que fizemos o upload e também os documentos. Substitua o conteúdo do arquivo pelo seguinte:
1234567891011121314151617181920212223242526272829303132333435363738394041424344<p id="notice"><%= notice %></p><p><strong>First name:</strong><%= @user.first_name %></p><p><strong>Last name:</strong><%= @user.last_name %></p><p><strong>Email:</strong><%= @user.email %></p><p><strong>About:</strong><%= @user.about %></p><hr /><h4>Avatar vários tamanhos</h4>Thumb:<%= image_tag(@user.avatar.thumb) if @user.avatar %>Medium:<%= image_tag(@user.avatar.medium) if @user.avatar %>Big:<%= image_tag(@user.avatar.big) if @user.avatar %><hr /><h4>Documentos</h4><% @user.documents.each_with_index do |document, index| %><%= link_to("Anexo #{index + 1} ", document.url, target: '_blank') %><br /><% end %><hr /><%= link_to 'Edit', edit_user_path(@user) %> |<%= link_to 'Back', users_path %> - Agora abra o browser e visite http://localhost/users.
- Crie um novo usuário passando um first_name, last_name, email, um avatar (photo) e vários arquivos no campo documents.
- Agora você vai ser redirecionado pro método show e vai poder ver as fotos em vários tamanhos e também os links para todos os documentos que você subiu.
- \o/ Parabéns nós conseguimos subir nossos arquivos.
CONCLUSÃO
O CarrierWave é uma Gem bem prática e te dá muita flexibilidade na hora de subir seus arquivos, então se você precisa implementar essa função no seu APP, esse pode ser um bom caminho para fazer isto.
Com a solução apresentada já é possível você cobrir grande parte dos casos de uso de upload de fotos e anexos mas caso você precise subir arquivos para uma Api Rails você pode usar a reviews zoosk dating site para fazer isso facilmente.
Com essa Gem você pode também subir os arquivos diretamente para o S3 da AWS e ter maior segurança por guardar as imagens na nuvem.
Como de costume o Código completo da aplicação está no Github, caso você queria clonar o código, https://onebitcode.com/internet-dating-meme/ Aproveita e me segue lá \o/
Se você ficou com dúvidas ou tem sugestões de posts para o Blog comenta aí em baixo ou me adiciona no Facebook https://onebitcode.com/absolute-and-relative-dating/.
Muito Obrigado,
Sua presença aqui é uma honra para mim,
Leonardo Scorza :)[:]