about ruby on rails...

Загрузка файлов на сервер с помощью плагина attachment_fu by Rick Olsen

In plugins on 13 сентября, 2009 at 23:46

При поиске описания по загрузке файлов на сервер большинство результатов приходится на данный плагин и статью Mike Clark по работе с ним.

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

Вступление: для работы с загружаемыми изображениями необходимы установленные ImageMagick и gem rmagick. Установка ImageMagick подробно описана на странице библиотеки, rmagick устанавливается с помощью gem install rmagick. Подозреваю, что если вы планируете работать не с изображениями, а с прочими файлами, надобности в установке ImageMagick и rmagick нет, но проверить пока нет возможности. Работу с иными файлами постараюсь описать в следующем посте.

Шаг 1. Создаем каркас нашего приложения

rails photos

И устанавливаем plugin

script/plugin install http://svn.techno-weenie.net/projects/plugins/attachment_fu/

Шаг 2. Создаем модель Photo

script/generate model Photo parent_id:integer content_type:string filename:string thumbnail:string size:integer width:integer height:integer

Создаем базу данных

rake db:create

Создаем таблицу photos в нашей базе данных

rake db:migrate

Назначение полей таблицы следующее:

  • parent_id — при создании миниатюр (thumbnail) устанавливается связь по данному полю между исходным изображением и миниатюрой
  • content_type — тип файла
  • filename — имя файла
  • thumbnail — тип миниатюры :thumb, :small etc., для исходного изображения содержит nil
  • size — размер файла
  • width, height — ширина и высота изображения

Шаг 3. Подкорректируем нашу модель:
Плагин позволяет добавить к нашей модели два метода has_attachment и validates_as_attachment

class Photo < ActiveRecord::Base
has_attachment :content_type => :image,
                          :storage => :file_system,
                          :resize_to => '800x640>',
                          :thumbnails => {:thumb => '100x100>'},
                          :max_size => 10.megabytes
 validates_as_attachment
end

:storage => :file_system устанавливает в качестве места хранения загруженных файлов файловую систему сервера. По умолчанию public/#{table_name}. Возможные варианты storage_type можно посмотреть в README.
:resize_to => '800x640>' меняем размер загружаемого изображения до указанных параметров. Как я понимаю, указание символа > позволяет сохранять пропорции при трансформации.
:thumbnails => {:thumb => '100x100>'} создаем миниатюру типа :thumb с указанными размерами.
:max_size => 10.megabytes ограничиваем размер загружаемого файла 10 Mb (ну не было у меня маленьких фотографий ))).
Метод validates_as_attachment проверяет загружаемый файл на соответствие указанным параметрам.

Шаг 4. Создаем контролер photos

script/generate controller photos index new create destroy

Я упростил наш контроллер оставив только 4 действия.

Шаг 5. Скорректируем сгенерированный контролер следующим образом

class PhotosController < ApplicationController
  def index
    @photos = Photo.find(:all, :conditions => {:thumbnail => nil})
  end

  def new
    @photo = Photo.new
  end

  def create
    @photo = Photo.new(params[:photo])
    if @photo.save
      redirect_to :action => 'index'
    else
      render :action => 'new'
    end
  end

  def destroy
    @photo = Photo.find(params[:id])
    @photo.destroy

    respond_to do |format|
      format.html { redirect_to :action => 'index' }
    end
  end

end

Действие index будет выводить миниатюру загруженных изображений.
new позволит выбирать новые фотографии для загрузки.
create будет загружать новые фотографии на сервер.
destroy будет удалять объекты из нашей базы данных и загруженные фотографии с сервера.

Шаг 6. Внесем следующую строку в файл config/routes.rb

map.resources :photos

Шаг 7. Измени сгенерированный по умолчанию шаблон index.html.erb

<head>
	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
	<title>Photos</title>
	<style type="text/css" media="screen">
		.photo_list {
			position: relative;
		}
		.entry {
			margin-left: 5px;
		 	float: left;
		}
		.links {
			clear: both;
		}
	</style>
</head>
<h1>Photo list</h1>
<div class="photo_list">
<% for photo in @photos -%>
	<div class="entry">
	<%= link_to image_tag(photo.public_filename(:thumb)), photo.public_filename %>
	<%= button_to "Удалить фото", photo_path(photo.id), :method => :delete %>
	</div>
<% end -%>
<div class="links">
<%= link_to "Добавить фото", new_photo_path %>
<div>
</div>

Шаг 8. Измени сгенерированный по умолчанию шаблон new.html.erb

<%= error_messages_for :photo %>

<% form_for(:photo, :url => photos_path,
                      :html => { :multipart => true }) do |f| -%>
  <p>
    <label for="photo">Выберите файл:</label>
    <%= f.file_field :uploaded_data %>
  </p>
  <p>
    <%= submit_tag 'Загрузить' %>
  </p>
<% end -%>

Указание :html => { :multipart => true } обязательно, для того чтобы форма позволяла вставить диалог выбора файла.

Шаг 9. Запускаем наше приложение и радуемся:

script/server

Оставьте комментарий