Учебники

Ruby on Rails 2.1 — загрузка файлов

У вас может быть требование, по которому вы хотите, чтобы посетители вашего сайта загружали файл на ваш сервер. Rails позволяет очень легко справиться с этим требованием. Теперь мы продолжим простой и маленький Rails-проект.

Как обычно, начнем с нового приложения на Rails под названием upload . Давайте создадим базовую структуру приложения с помощью простой команды rails.

C:\ruby> rails -d mysql upload

Давайте решим, где вы хотели бы сохранить загруженные файлы. Предположим, это каталог данных внутри вашего публичного раздела. Итак, создайте этот каталог и проверьте разрешения.

C:\ruby> cd upload
C:\ruby\upload> mkdir upload\public\data

Нашим следующим шагом, как обычно, будет создание контроллера и моделей.

Создание модели

Поскольку это не приложение на основе базы данных, мы можем сохранить любое имя, которое нам удобно. Предположим, мы должны создать модель DataFile .

C:\ruby\upload> ruby script/generate model DataFile
   exists  app/models/
   exists  test/unit/
   exists  test/fixtures/
   create  app/models/data_file.rb
   create  test/unit/data_file_test.rb
   create  test/fixtures/data_files.yml
   create  db/migrate
   create  db/migrate/001_create_data_files.rb   

Теперь мы создадим метод с именем save в файле модели data_file.rb . Этот метод будет вызываться контроллером приложения.

class DataFile < ActiveRecord::Base
   def self.save(upload)
      name = upload['datafile'].original_filename
      directory = "public/data"
      # create the file path
      path = File.join(directory, name)
      # write the file
      File.open(path, "wb") { |f| f.write(upload['datafile'].read) }
   end
end

Вышеприведенная функция примет загрузку объекта CGI и извлечет имя загруженного файла, используя вспомогательную функцию original_filename, и, наконец, сохранит загруженный файл в каталог «public / data». Вы можете вызвать вспомогательную функцию content_type, чтобы узнать тип мультимедиа загруженного файла.

Здесь File — это объект ruby, а join — вспомогательная функция, которая объединяет имя каталога вместе с именем файла и возвращает полный путь к файлу.

Далее, чтобы открыть файл в режиме записи, мы используем функцию open helper, предоставляемую объектом File . Далее мы читаем данные из переданного файла данных и записываем в выходной файл.

Создание контроллера

Теперь давайте создадим контроллер для нашего проекта загрузки —

C:\ruby\upload> ruby script/generate controller Upload
   exists  app/controllers/
   exists  app/helpers/
   create  app/views/upload
   exists  test/functional/
   create  app/controllers/upload_controller.rb
   create  test/functional/upload_controller_test.rb
   create  app/helpers/upload_helper.rb

Теперь мы создадим две функции контроллера. Первый индекс функции вызывает файл представления для ввода данных пользователем, а вторая функция uploadFile получает информацию о файле от пользователя и передает ее в модель «DataFile». Мы устанавливаем каталог загрузки в каталог «uploads», который мы создали ранее «directory = ‘data'».

class UploadController < ApplicationController
   def index
      render :file => 'app\views\upload\uploadfile.html.erb'
   end
   def uploadFile
      post = DataFile.save( params[:upload])
      render :text => "File has been uploaded successfully"
   end
end

Здесь мы вызываем функцию, определенную в файле модели. Функция рендеринга используется для перенаправления для просмотра файла, а также для отображения сообщения.

Создание представления

Наконец, мы создадим файл представления uploadfile.rhtml, который мы упомянули в контроллере. Заполните этот файл с помощью следующего кода —

<h1>File Upload</h1>

<% form_tag ({:action => 'uploadFile'},
   :multipart => true) do %>

<p><label for="upload_file">Select File</label> : 

<%= file_field 'upload', 'datafile' %></p>

<%= submit_tag "Upload" %>

<% end %>

Здесь все то же самое, что мы объяснили в предыдущих главах. Единственный новый тег — file_field , который создаст кнопку для выбора файла с компьютера пользователя.

Установив для параметра multipart значение true, вы гарантируете, что ваше действие правильно передает двоичные данные из файла.

Здесь важно отметить, что мы присвоили «uploadFile» в качестве имени метода в : action , который будет вызываться при нажатии кнопки « Upload» .

Он покажет вам экран следующим образом —

Загрузить файл

Теперь вы выбираете файл и загружаете его. Этот файл будет загружен в каталог app / public / data с фактическим именем файла, и появится сообщение о том, что «Файл был успешно загружен».

ПРИМЕЧАНИЕ. — Если файл с таким именем уже существует в выходном каталоге, он будет перезаписан.

Файлы, загруженные из Internet Explorer

Internet Explorer включает полный путь к файлу в отправляемом имени файла, поэтому процедура original_filename будет возвращать что-то вроде —

C:\Documents and Files\user_name\Pictures\My File.jpg

Вместо просто —

My File.jpg

Это легко обрабатывается File.basename , который удаляет все перед именем файла.

def sanitize_filename(file_name)
   # get only the filename, not the whole path (from IE)
   just_filename = File.basename(file_name) 
   # replace all none alphanumeric, underscore or perioids
   # with underscore
   just_filename.sub(/[^\w\.\-]/,'_') 
end

Удаление существующего файла

Если вы хотите удалить какой-либо существующий файл, это довольно просто. Все, что вам нужно сделать, это написать следующий код —

def cleanup
   File.delete("#{RAILS_ROOT}/dirname/#{@filename}") 
   if File.exist?("#{RAILS_ROOT}/dirname/#{@filename}")
end

Чтобы получить более подробную информацию об объекте File , вам нужно ознакомиться с нашим справочным руководством по Ruby .