Ruby on Rails - Upload de arquivo

Você pode ter um requisito no qual deseja que os visitantes do site carreguem um arquivo em seu servidor. Rails torna muito fácil lidar com esse requisito. Agora vamos prosseguir com um projeto Rails simples e pequeno.

Como de costume, vamos começar com um novo aplicativo Rails chamado testfile. Vamos criar a estrutura básica do aplicativo usando o comando rails simples.

tp> rails new testfile

Antes de iniciar o desenvolvimento do aplicativo, devemos instalar os arquivos gem conforme mostrado abaixo -

gem install carrierwave
gem install bootstrap-sass

Abra seu gemfile e adicione as duas joias a seguir na parte inferior, conforme mostrado na imagem a seguir -

Depois de adicionar gems no arquivo gem, precisamos executar o seguinte comando no console -

bundle install

Criando o modelo

Precisamos criar um modelo com duas strings como nome e anexo, conforme mostrado abaixo -

rails g model Resume name:string attachment:string

Precisamos criar a migração do banco de dados conforme mostrado abaixo -

rake db:migrate

Precisamos gerar o controlador conforme mostrado abaixo -

rails g controller Resumes index new create destroy

Ótimo! Agora temos a estrutura básica configurada. Agora precisamos criar um uploader. Um Uploader veio do carrierwave gem e diz ao carrierwave como lidar com os arquivos. Resumindo, ele continha todas as funcionalidades de processamento de arquivos. Execute o comando para criar um uploader conforme mostrado abaixo

rails g uploader attachment

Agora abra o modelo de currículo e chame o uploader conforme mostrado abaixo. O modelo de currículo foi colocado em app / models / resume.rb -

class Resume < ActiveRecord::Base
   mount_uploader :attachment, AttachmentUploader # Tells rails to use this uploader for this model.
   validates :name, presence: true # Make sure the owner's name is present.
end

Antes de trabalhar no controlador, precisamos modificar nosso config / routes.db conforme mostrado abaixo -

CarrierWaveExample::Application.routes.draw do
   resources :resumes, only: [:index, :new, :create, :destroy]
   root "resumes#index"
end

Permite-nos editar o controlador conforme mostrado abaixo.

class ResumesController < ApplicationController
   def index
      @resumes = Resume.all
   end
   
   def new
      @resume = Resume.new
   end
   
   def create
      @resume = Resume.new(resume_params)
      
      if @resume.save
         redirect_to resumes_path, notice: "The resume #{@resume.name} has been uploaded."
      else
         render "new"
      end
      
   end
   
   def destroy
      @resume = Resume.find(params[:id])
      @resume.destroy
      redirect_to resumes_path, notice:  "The resume #{@resume.name} has been deleted."
   end
   
   private
      def resume_params
      params.require(:resume).permit(:name, :attachment)
   end
   
end

Vamos adicionar a implementação de bootstrap no arquivo css file.css pode estar em app / assets / stylesheets / resumes.css.scss

@import "bootstrap";

Agora abra app / views / layouts / application.html.erb e adicione os códigos conforme mostrado abaixo -

<!DOCTYPE html>
<html>
   
   <head>
      <title>Tutorialspoint</title>
      <%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %>
      <%= javascript_include_tag "application", "data-turbolinks-track" => true %>
      <%= csrf_meta_tags %>
   </head>
   
   <body>
      <div class = "container" style = "padding-top:20px;">
         <%= yield %>
      </div>
   </body>

</html>

Agora precisamos configurar as visualizações de índice conforme mostrado abaixo -

<% if !flash[:notice].blank? %>
   <div class = "alert alert-info">
      <%= flash[:notice] %>
   </div>
<% end %>

<br />

<%= link_to "New Resume", new_resume_path, class: "btn btn-primary" %>
<br />
<br />

<table class = "table table-bordered table-striped">
   <thead>.
      <tr>
         <th>Name</th>
         <th>Download Link</th>
         <th> </th>
      </tr>
   </thead>
   
   <tbody>
      <% @resumes.each do |resume| %>
         
         <tr>
            <td><%= resume.name %></td>
            <td><%= link_to "Download Resume", resume.attachment_url %></td>
            <td><%= button_to "Delete",  resume, method: :delete, class: "btn btn-danger", confirm: "Are you sure that you wish to delete #{resume.name}?" %></td>
         </tr>
         
      <% end %>
   </tbody>
   
</table>

Agora, vamos editar new.html.erb e adicionar nosso código de formulário.

<% if [email protected]? %>
   <div class = "alert alert-error">
      
      <ul>
         <% @resume.errors.full_messages.each do |msg| %>
            <li><%= msg %></li>
         <% end %>
      </ul>
      
   </div>
<% end %>

<div class = "well">
   <%= form_for @resume, html: { multipart: true } do |f| %>
      <%= f.label :name %>
      <%= f.text_field :name %>
      <%= f.label :attachment %>
      <%= f.file_field :attachment %>
      <%= f.submit "Save", class: "btn btn-primary" %>
   <% end %>
</div>

Agora inicie o servidor e visite http: // localhost: 3000. Ele produzirá uma tela semelhante à seguinte -

Uma última coisa que precisamos fazer é filtrar a lista de tipos de arquivos permitidos. Para isso, precisamos adicionar um código simples, conforme mostrado abaixo em app / uploaders / attachment_uploader.rb

class AttachmentUploader < CarrierWave::Uploader::Base
   storage :file
   
   def store_dir
      "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
   end
   
   def extension_white_list
      %w(pdf doc htm html docx)
   end
end

Agora inicie o servidor e visite http: // localhost: 3000. Agora insira um formato errado; irá gerar uma mensagem errada como mostrado abaixo -

Para um detalhe completo sobre File objeto, você precisa passar pelo Ruby Reference Manual.