во View:
<%= start_form_tag({:action => "save_user"}, :multipart => true) %>
Photo:
<%= file_field("user", "photofile") %>
<%= end_form_tag %>
в контроллере:
def save_user
pfile = params[:user][:photofile]
if pfile.original_filename.size > 0
File.open("#{RAILS_ROOT}/public/images/photo/photo1.jpg", "wb") do |f|
f.write(pfile.read)
end
end
end
Но это просто аплоад файлов. А надо аплоадить только картинки jpg. Как
задать такое условие?
--
С уважением, Den
icq# 301033169
Вобщем-то аплоад файлов одна из самых гимморойных задач под веб. И что под пхп
что под рейлс приходится мудохаться чтобы сделать это универсально и один
раз.
Есть много подводных камней. Например, чтобы тебе не залили пхп-ешный файл и
не хакнули сервер. Или чтобы новая картинка не затерла старую. Кроме того,
если используешь картинки, часто нужно их ресайзить. При этом если это гифка
иногда ее приходится приводить к jpg-у или png чтобы вид был симпатичный.
Опять же, отресайзенную картинку нужно правильно обозвать что-то типа
image-small.gif и т.п.
Кроме того, в админке желательно делать превью в форме админки, чтобы было
видно, что ты залил. Но будет некрасиво если эта картинка будет большая и
разнесет тебе форму на весь экран - и нужно делать ресайз джаваскриптом.
И на добавку кинем флеш. Это вообще отдельная песня, уже для того, чтобы
сделать его вывод, нужно знать его размеры, а как ты узнаешь размеры
флеш-картинки, если сам же их и не задашь.
Ну что, испугался? :))
Вот две ссылки:
Acts as Attachment in Plugins:
http://technoweenie.stikipad.com/plugins/show/Acts+as+Attachment
file_column plugin: http://www.kanthak.net/opensource/file_column/
Звезд с неба не ловят, но позволяют не морочиться с проверками расширений и
самим аплоадом файла.
--
Serhiy Boiko
CRIS-UANIC
А за это спасибо, действительно хорошая идея :).
--
Serhiy Boiko
CRIS-UANIC
# acts_as_attachment :content_type => 'application/pdf'
# acts_as_attachment :content_type => ['application/pdf',
'application/msword', 'text/plain']
# acts_as_attachment :content_type => :image, :resize_to =>
[50,50]
http://svn.techno-weenie.net/projects/plugins/acts_as_attachment/
http://technoweenie.stikipad.com/plugins/show/Acts+as+Attachment
On 03.10.2006, at 14:18, Denis Surkov wrote:
> Как можно реализовать сабж? Пока использую такое:
--
Yaroslav Markin
yaroslav at markin dot net
http://www.evilmartians.com/
http://www.rubyonrails.ru/
Вы писали 3 октября 2006 г., 18:02:05:
> Чтобы не изобретать велосипед, смотри на acts_as_attachment
А вот расскажите как сделать при помощи этого плагина более одной
картинки?
--
С уважением,
Timur mailto:tim...@gmail.com
> А вот расскажите как сделать при помощи этого плагина более одной
> картинки?
>
Item
has_many :pictures
Picture
belongs_to :item
acts_as_attachment
или ты что-то другое имел в виду?
Или ты про изменение размеров картинок? Там все это есть, нормальная
работа с rmagick, для каждого acts_as_attachment делается несколько
thumbs, у каждого parent_id указывает на родительский элемент
Вы писали 3 октября 2006 г., 18:41:17:
> On 03.10.2006, at 18:35, Timur Vafin wrote:
>> А вот расскажите как сделать при помощи этого плагина более одной
>> картинки?
> Item
> has_many :pictures
> Picture
> belongs_to :item
> acts_as_attachment
> или ты что-то другое имел в виду?
Ну как то мне кажется это намного сложнее, чем просто
описать у модели, что у нее есть большая картинка и маленькая
картинка, что позволяет делать file_column.
Давай будем писать вопросы покорректнее :)
acts_as_attachment :content_type => :image, :resize_to => [50,50]
acts_as_attachment :thumbnails => { :thumb => [50, 50], :geometry =>
'x50' }
То что ты можешь сделать в file_column, ты можешь сделать и здесь.
Лично я больше fc не пользуюсь.
Вот именно, покорректнее
Большая и маленькая картинки абсолютно разные.
Например, большая - это фотография меня в полный рост, а маленькая -
морда забавной собачки. Как такое сделать?
--
Best regards, Dmytro Shteflyuk
Вы писали 3 октября 2006 г., 19:23:52:
>>>> А вот расскажите как сделать при помощи этого плагина более одной
>>>> картинки?
>>
>>> Item
>>> has_many :pictures
>>
>>> Picture
>>> belongs_to :item
>>> acts_as_attachment
>>
>>> или ты что-то другое имел в виду?
>>
>> Ну как то мне кажется это намного сложнее, чем просто
>> описать у модели, что у нее есть большая картинка и маленькая
>> картинка, что позволяет делать file_column.
> Давай будем писать вопросы покорректнее :)
> acts_as_attachment :content_type => :image, :resize_to => [50,50]
> acts_as_attachment :thumbnails => { :thumb => [50, 50], :geometry =>
> 'x50' }
Что то видимо я не до конца разобрался.
У меня было представление что к модели можно привязать только одно
изображение.
Если конкретизировать, то как сделать чтобы у модели были 2 разные
картинки =)
> Что то видимо я не до конца разобрался.
>
> У меня было представление что к модели можно привязать только одно
> изображение.
>
> Если конкретизировать, то как сделать чтобы у модели были 2 разные
> картинки =)
>
Смотри, если нужно чтобы было просто две разные картинки -- то это
has_many отношение: у модели есть много картинок.
Если тебе надо делать уменьшенные копии картинок, например
(thumbnails) -- то такая возможность зашита и в file_column, и в
acts_as_attachment. В AAA можно вешаться на after_resize,
after_attachment_saved, before_thumbnail_saved и всякое такое.
Тогда это по смыслу две разные картинки -- две разные модели которые
относятся к родительской.
> Вот именно, покорректнее
> Большая и маленькая картинки абсолютно разные.
> Например, большая - это фотография меня в полный рост, а маленькая -
> морда забавной собачки. Как такое сделать?
Да, и если ни thumbnails, ни has_many не подходят, то, как и всегда,
есть два универсальных варианта
1. Сделать таблицу attachments и Attachment, и наследовать его как
single table inheritance
2. Использовать polymorphic associations на эту таблицу
Вы писали 3 октября 2006 г., 19:40:31:
> On 03.10.2006, at 19:29, Dmytro Shteflyuk wrote:
>> 2006/10/3, Yaroslav Markin <yaro...@markin.net>:
>>> Давай будем писать вопросы покорректнее :)
>>>
>>> acts_as_attachment :content_type => :image, :resize_to => [50,50]
>>> acts_as_attachment :thumbnails => { :thumb => [50, 50], :geometry =>
>>> 'x50' }
>>
>> Вот именно, покорректнее
>> Большая и маленькая картинки абсолютно разные.
>> Например, большая - это фотография меня в полный рост, а маленькая -
>> морда забавной собачки. Как такое сделать?
> Тогда это по смыслу две разные картинки -- две разные модели которые
> относятся к родительской.
Тогда ясно, я сталкивался с тем что у моделей просто бывает несколько
изображений различных.
Думаю в случае file_column это сделать много проще =)
Тут примерно такая задача:
1. Сохранять любые файлы с картинками
только в предопределенном расширении.
2. Сохранять сразу несколько версий
размеров.
#controller
class ImagesController < ApplicationController
...
def create_me
if Photo.exists?(params[:photo_id].to_i)
@photo = Photo.find(params[:photo_id].to_i)
@photo.file = @params[:testfile][:file]
else
@photo = Photo.new(@params[:testfile])
end
redirect_to :action => 'new_image'
end
...
end
redirect_to :action => 'new_image'
end
#model
require 'RMagick'
require 'digest/md5'
class Photo < ActiveRecord::Base
STORE_DIR = "#{RAILS_ROOT}/public/photos"
MAIN_EXT = 'png'
@@versions = {:MAIN => '320x240', :thumb => '100x100'}
before_destroy :before_destroy
...
def file=(uploaded_file)
@uploaded_file = uploaded_file
if self.new_record?
@filename = "#{general_name}.#{MAIN_EXT}"
else
@filename = self.photo
end
self.photo = @filename
end
def after_save
if !File.exists?(File.dirname(path_to_file))
Dir.mkdir(File.dirname(path_to_file))
end
if @uploaded_file.instance_of?(Tempfile)
FileUtils.copy(@uploaded_file.local_path, path_to_file)
else
File.open(self.path_to_file, "wb") { |f|
f.write(@uploaded_file.read) }
end
saved_file = ::Magick::Image.read(self.path_to_file).first
@@versions.each{|key,value|
saved_file.clone.change_geometry!(value) { |cols, rows, img|
img.resize!(cols, rows)
file_name = self.photo.split('.').first
if key.to_s =~ /MAIN/i
img.write File.join(STORE_DIR,"#{file_name}_.#{MAIN_EXT}")
else
img.write
File.join(STORE_DIR,"#{file_name}_#{key.to_s}.#{MAIN_EXT}")
end
}
}
if File.exists?(path_to_file)
File.delete(path_to_file)
end
end
...
end
Все это взято/переделано/упращено из
из того же file_column.
Если заинтересует, то могу помочь, если
что то непонятно, или же переслать
рабочий проект.
>> Тогда это по смыслу две разные картинки -- две разные модели которые
>> относятся к родительской.
>
> Тогда ясно, я сталкивался с тем что у моделей просто бывает несколько
> изображений различных.
>
> Думаю в случае file_column это сделать много проще =)
В file_column изображение -- это просто ссылка на файл, а в AAA это
все-таки модель. Когда как удобнее..
Делать там на самом деле не много. Так что если надо захранить две картинки
для одного экземпляра, например, пользователя, не надо перекраивать и
выделять их в новую сущность. Такая нормализация сама по себе, конечно,
хорошая вещь, но она может понизить производительность.
К тому же, поток - потоком, а валидации таки отделились от моделей (см.
ActiveSpec)
> Схема (на основе идентификатора обьекта к
> которому привязан аттачмент) сделана
> таким образом
> чтобы предотвратить переполнение
> директирии (большинство опенсорсных
> файловых систем начинают очень круто
> кашлять при превышении определенного
> количества записей в директории).
Меня волновал не ID, а то, что он привязывается к classname/attributename/.
Мне надо было, чтобы все (немногочисленные) файлики одного экземпляра модели
лежали в, к примеру, mymodel/id/ и назывались myattribute<n>.<correct
extension>
А в file_column один аттрибут - это отдельная папочка, где он складывает
подпапки, соответствующие id объектов. Похоже по дефолты сделаны routes:
:controller/:action/:id
вместо
:controller/:id/:action
В случае последних тут все понятно - есть экшены, которым не нужен id. А вот с
file_column - имхо, большой минус.
Ну как же отделились, как я понял ActiveSpec
это сторонний проект, просто автор
заюзал префикс Active
Но теперь это "научно обоснованный" =) подход.
Спецификации при определенном использовании идентичны существующим в Rails
валидациям , но, имхо, сами по себе более удобные.