У вас может быть требование, по которому вы хотите, чтобы посетители вашего сайта загружали файл на ваш сервер. 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 .