Ruby on Rails - Tải lên tệp

Bạn có thể có một yêu cầu trong đó bạn muốn khách truy cập trang web của mình tải lên một tệp trên máy chủ của bạn. Rails làm cho nó rất dễ dàng để xử lý yêu cầu này. Bây giờ chúng ta sẽ tiến hành một dự án Rails đơn giản và nhỏ.

Như thường lệ, hãy bắt đầu với một ứng dụng Rails mới có tên testfile. Hãy tạo cấu trúc cơ bản của ứng dụng bằng cách sử dụng lệnh rails đơn giản.

tp> rails new testfile

Trước khi bắt đầu phát triển ứng dụng, chúng ta nên cài đặt các tệp gem như hình dưới đây -

gem install carrierwave
gem install bootstrap-sass

Mở tệp gem của bạn và thêm hai viên ngọc sau vào dưới cùng như thể hiện trong hình sau:

Sau khi thêm đá quý trong tệp đá quý, chúng ta cần chạy lệnh sau trên bảng điều khiển:

bundle install

Tạo mô hình

Chúng ta cần tạo một mô hình với hai chuỗi là tên và tệp đính kèm như hình dưới đây -

rails g model Resume name:string attachment:string

Chúng ta cần tạo quá trình di chuyển cơ sở dữ liệu như hình dưới đây:

rake db:migrate

Chúng ta cần tạo bộ điều khiển như hình dưới đây -

rails g controller Resumes index new create destroy

Tuyệt quá! Bây giờ chúng ta đã thiết lập cấu trúc cơ bản. Bây giờ chúng ta cần tạo một trình tải lên. Trình tải lên đến từ đá quý của hãng vận chuyển và nó cho người vận chuyển biết cách xử lý các tệp. Tóm lại, nó chứa tất cả các chức năng xử lý tệp. Chạy lệnh để tạo trình tải lên như hình dưới đây

rails g uploader attachment

Bây giờ mở mô hình lý lịch và gọi người tải lên như hình dưới đây. Mô hình hồ sơ đã được đặt tại 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

Trước khi làm việc trên bộ điều khiển, chúng ta cần sửa đổi cấu hình / route.db của mình như hình dưới đây:

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

Cho phép chúng tôi chỉnh sửa bộ điều khiển như hình dưới đây.

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

Hãy thêm triển khai bootstrap trong tệp css file.css có thể nằm trong app / asset / stylesheets / resumes.css.scss

@import "bootstrap";

Bây giờ, hãy mở app / views / layouts / application.html.erb và thêm mã như hình dưới đây -

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

Bây giờ chúng ta cần thiết lập chế độ xem chỉ mục như hình dưới đây:

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

Bây giờ, hãy chỉnh sửa new.html.erb và thêm mã biểu mẫu của chúng tôi.

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

Bây giờ khởi động máy chủ và truy cập http: // localhost: 3000. Nó sẽ tạo ra một màn hình tương tự như sau:

Một điều cuối cùng chúng ta cần làm là lọc danh sách các loại tệp được phép. Đối với điều đó, chúng tôi cần thêm mã đơn giản như được hiển thị bên dưới tại 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

Bây giờ khởi động máy chủ và truy cập http: // localhost: 3000. Bây giờ nhập một định dạng sai; nó sẽ tạo ra một thông báo sai như hình dưới đây -

Để biết chi tiết đầy đủ về File đối tượng, bạn cần phải đi qua Ruby Reference Manual.