Ruby on Rails - Carga de archivos

Es posible que tenga un requisito en el que desee que los visitantes de su sitio carguen un archivo en su servidor. Rails hace que sea muy fácil manejar este requisito. Ahora procederemos con un proyecto de Rails simple y pequeño.

Como de costumbre, comencemos con una nueva aplicación Rails llamada testfile. Creemos la estructura básica de la aplicación usando un comando simple de rieles.

tp> rails new testfile

Antes de comenzar el desarrollo de la aplicación, debemos instalar los archivos gem como se muestra a continuación:

gem install carrierwave
gem install bootstrap-sass

Abra su archivo de gemas y agregue las siguientes dos gemas en la parte inferior como se muestra en la siguiente imagen:

Después de agregar gemas en el archivo de gemas, debemos ejecutar el siguiente comando en la consola:

bundle install

Creando el modelo

Necesitamos crear un modelo con dos cadenas como nombre y archivo adjunto como se muestra a continuación:

rails g model Resume name:string attachment:string

Necesitamos crear la migración de la base de datos como se muestra a continuación:

rake db:migrate

Necesitamos generar el controlador como se muestra a continuación:

rails g controller Resumes index new create destroy

¡Excelente! Ahora tenemos la estructura básica configurada. Ahora necesitamos crear un cargador. Un Uploader vino de carrierwave gem y le dice a carrierwave cómo manejar los archivos. En resumen, contenía todas las funcionalidades de procesamiento de archivos. Ejecute el comando para crear un cargador como se muestra a continuación

rails g uploader attachment

Ahora abra el modelo de currículum y llame al cargador como se muestra a continuación. El modelo de currículum se ha colocado en 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 trabajar en el controlador, necesitamos modificar nuestro config / routes.db como se muestra a continuación:

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

Vamos a editar el controlador como se muestra a continuación.

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

Agreguemos la implementación de bootstrap en el archivo css. El archivo css podría estar en app / assets / stylesheets / resumes.css.scss

@import "bootstrap";

Ahora abra app / views / layouts / application.html.erb y agregue códigos como se muestra a continuación:

<!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>

Ahora necesitamos configurar vistas de índice como se muestra a continuación:

<% 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>

Ahora, editemos new.html.erb y agreguemos nuestro código de formulario.

<% 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>

Ahora inicie el servidor y visite http: // localhost: 3000. Producirá una pantalla similar a la siguiente:

Una última cosa que debemos hacer es filtrar la lista de tipos de archivos permitidos. Para eso, necesitamos agregar un código simple como se muestra a continuación en app / uploaders / attach_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

Ahora inicie el servidor y visite http: // localhost: 3000. Ahora ingrese un formato incorrecto; generará un mensaje incorrecto como se muestra a continuación -

Para un detalle completo sobre File objeto, debe pasar por el Ruby Reference Manual.