Ранее: запуск метода модели во вложении скрепки после создания или обновления (обратные вызовы скрепки не работают)
Редактировать (позже в тот же день)
Я понял мою проблему. Процессор, очевидно, работает с файлом, который обновляется, но не сохраняет никаких файлов до окончания обработки. Я изменил свой Zip :: ZipFile, чтобы открыть «файл», а не «attachment.path», так как путь к вложению на самом деле еще ничего не содержит. Это решило первую проблему. Теперь у меня другие проблемы, которые мне нужно отследить. Но ответ ниже в основном правильный.
Изменить (31.01.2011):
Итак, я воспользовался советом по созданию процессора для моего вложения, который будет выполнять все необходимые действия. Пока что похоже, что это должно работать; процессор запускается и выполняет все действия по инициализации, по-видимому. Однако, когда я получаю сообщение о том, что хочу получить доступ к загружаемому zip-файлу, я получаю сообщение об ошибке, в котором говорится, что файл не найден. Код для моего процессора ниже:
class Extractor < Processor
attr_accessor :resolution, :whiny
def initialize(file, options = {}, attachment = nil)
super
@file = file
@whiny = options[:whiny].nil? ? true : options[:whiny]
@basename = File.basename(@file.path, File.extname(@file.path))
@attachment = attachment
@instance = attachment.instance
end
def make
# do your conversions here, you've got @file, @attachment and @basename to work with
export_path = attachment.path.gsub('.zip', '_content')
Zip::ZipFile.open(attachment.path) { |zip_file|
zip_file.each { |image|
image_path = File.join(export_path, image.name)
FileUtils.mkdir_p(File.dirname(image_path))
unless File.exist?(image_path)
zip_file.extract(image, image_path)
# ..stuff that it does..
end
}
}
# clean up source files, but leave the zip
FileUtils.remove_dir(export_path)
# you return a file handle which is the processed result
dst = File.open result_file_path
end
end
И вот содержание ошибки, которую я получаю:
Zip::ZipError in GalleriesController#create
File /home/joshua/railscamp/moments_on_three/public/assets/archives/delrosario.zip not found
Rails.root: /home/joshua/railscamp/moments_on_three
Application Trace | Framework Trace | Full Trace
config/initializers/extractor.rb:16:in `make'
app/controllers/galleries_controller.rb:32:in `new'
app/controllers/galleries_controller.rb:32:in `create'
Request
Parameters:
{"utf8"=>"✓",
"authenticity_token"=>"0s4L4MrlqjDTMjzjgkUdvUxeHklZNOIShDhT6fgOICY=",
"gallery"=>{"name"=>"DelRosario",
"public"=>"0",
"owner_id"=>"1",
"shoot_date(1i)"=>"2011",
"shoot_date(2i)"=>"1",
"shoot_date(3i)"=>"31",
"category_id"=>"1",
"archive"=>#<ActionDispatch::Http::UploadedFile:0x00000004148d78 @original_filename="delrosario.zip",
@content_type="application/zip",
@headers="Content-Disposition: form-data; name=\"gallery[archive]\"; filename=\"delrosario.zip\"\r\nContent-Type: application/zip\r\n",
@tempfile=#<File:/tmp/RackMultipart20110131-9745-14u347v>>},
"commit"=>"Create Gallery"}
Из того, что я могу сказать, он ищет файл в нужном месте, но, похоже, файл еще не загружен для доступа к нему. Насколько я знаю, Paperclip достаточно умен, чтобы знать и ждать загрузки вложения, прежде чем оно попытается его обработать. Кто-нибудь может заметить, что я здесь делаю неправильно?
Большое спасибо.
Старые вещи:
Я занимаюсь разработкой приложения для создания фотогалереи с использованием Rails 3 и Paperclip. Администратор может создать галерею и загрузить ZIP-файл, содержащий несколько изображений.
Что я хочу, чтобы произошло:
- Введите информацию о галерее и zip-файл для загрузки в форму.
- Нажмите кнопку «Создать галерею».
- Формируйте сообщения, сохраняйте галерею и загружайте zip-файл.
- После загрузки zip-файла запустите метод: extract_photos (кстати, этот код
работает).
4.a. В конце этого метода zip-файл уничтожается.
- Администратор перенаправлен на страницу галереи со всеми фотографиями в ней (где
галерея имеет много фотографий).
Я пытался сделать эту работу несколькими разными способами.
Раньше я создавал метод контроллера, который позволял бы администратору щелкать ссылку, которая запускала метод: extract_photos. Это работало на моем компьютере, но по какой-то причине у сервера возникли проблемы с маршрутизацией на компьютере клиента. Так что это не пойдет. К тому же я думал, что это уродливый способ сделать это.
Недавно я попытался использовать методы обратного вызова. after_save не работал, потому что он явно прерывает форму POST, и файл не загружается, а метод: extract_photos не может найти файл.
Я проверил методы обратного вызова на странице github Paperclip, и он говорит о обратных вызовах:
До и после постобработки
шаг, скрепка перезванивает
модель с несколькими обратными вызовами, позволяющая
модель, чтобы изменить или отменить
этап обработки. Обратные вызовы
"before_post_process" и
"after_post_process" (которые называются
до и после обработки
каждое вложение), а
прикрепление конкретных
"beforepost_process" и
"Afterpost_process". Обратные вызовы
должен быть как можно ближе к нормальному
ActiveRecord обратные вызовы, насколько это возможно, так
если вы вернете false (в частности,
возвращение ноль не то же самое) в
перед фильтром, постобработка
шаг остановится. Возвращая ложь в
после фильтра ничего не остановится,
но вы можете получить доступ к модели и тому
вложение при необходимости.
Я пытался использовать before_post_process и after_post_process, но он не может найти файл для запуска процесса, поэтому файл, очевидно, не загружается к тому времени, когда эти методы вызываются (что я считаю странным). Кроме того, когда я пытаюсь выполнить beforepost_process и afterpost_process, я получаю NoMethodError.
Так как мне вызвать метод для вложения, когда он создается или обновляется, но после загрузки файла и в нужном месте?
UPDATE
Я попробовал приведенный ниже код, переместив код метода извлечения в метод make процессора. Я продвинулся дальше, чем раньше, пытаясь написать процессор, но он все еще не запущен. Процесс выдает исключение, как только я пытаюсь открыть загруженный файл для обработки, говоря, что файл не существует. Схема именования верна и все, но все еще ничего не загружается до того, как процесс запускается. У кого-нибудь есть идеи, почему это происходит?