Rails3, S3, Paperclip Attachment как его собственная модель? - PullRequest
2 голосов
/ 11 января 2011

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

Модель Photo содержит все эти метаданные, и яиспользуя Paperclip, чтобы прикрепить фактический файл изображения к модели и сохранить изображения в Amazon S3.

В настоящее время взаимодействие с пользователем работает следующим образом:

  1. Пользователь нажимает «Добавить фото» ипереносится на страницу «Новое фото», где ему представляется форма.
  2. Первым делом в форме выбирается файл.Пользователь выбирает файл.
  3. Ниже приведены несколько различных полей метаданных, которые пользователь должен заполнить, поэтому пользователь заполняет их.
  4. Пользователь нажимает кнопку Отправить, файл загружается иновый объект Photo создан, пользователь перенаправлен на другую страницу.

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

Я полагаю, что я мог бы добиться этого, если бы я разделил файл изображения на его собственную модель, но тогда я буду ссылаться на изображения следующим образом:

@photo.attachment.file.url вместо более простого @photo.file.url, который я используюсейчас.Я бы предпочел не «вкладывать» это глубже, чем нужно.

Кроме того, разделение его на две модели поднимает проблему управления сиротами, с которой мне в настоящее время не приходится иметь дело.

Итак, мои вопросы:

  1. Есть ли хороший способ - предпочтительно , а не с использованием Flash - создать такое поведение асинхронной загрузки без разделения на две модели, ИЛИ -
  2. Если я должен разделить метаданные и файл на две модели, есть ли способ заставить Paperclip рассматривать вложение как его собственную модель, чтобы я мог получить к нему доступ, используя вместо этого <modelname>.<paperclip_method>из <model_name>.<attachment_attribute>.<paperclip_method>?

Я знаю, что это большой вопрос, поэтому большое спасибо заранее за вашу помощь!

Ответы [ 5 ]

1 голос
/ 06 мая 2011

Просто интересно, разве вы не устанавливаете зависимый пункт в вашей ассоциации?Например,

Class Photo < ActiveRecord::Base
  :has_one :attachment, :dependent => :destroy
end

Это предотвратит потерянные записи, так как каждый раз, когда вызывается метод уничтожения для Photo, он сначала выполняет Photo.attachment.destroy.Он также работает с: has_many.

1 голос
/ 16 января 2011

После недели экспериментов я просто подумал, что опубликую то, что я наконец-то сделал:

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

  1. Это упростило работу в рамках соглашения Rails (используйте стандартные действия REST для второй модели для обработки асинхронных обновлений)вместо того, чтобы добавлять несколько пользовательских действий в родительскую модель).

  2. Независимо от того, какой вариант я пробовал, я в конечном итоге получал бесхозные записи.Я обнаружил, что проще иметь родительский объект, который никогда не будет сохранен, если он не действителен (модель Photo в моем случае), и иметь вложения, которые могут быть сиротами.Вложения никогда не вызываются напрямую нигде в приложении, поэтому нет риска случайного появления пустой записи и не нужно устанавливать область по умолчанию или что-то еще, чтобы показывать только «действительные» фотографии.Очистить детей-сирот довольно легко, просто сделайте Attachment.where( :parent_id => nil ) и удалите все эти.

  3. Я могу сохранить предыдущий код, просто делегировав приложение к фотографии.См. этот ответ по другому вопросу.

Надеюсь, это избавит других от некоторых неприятностей в будущем.Если вам нужны функциональные возможности Ajax с вложениями, лучше сделать их собственную модель.Кроме того, для добавления загрузки ajax-файла в формы, проверьте https://github.com/formasfunction/remotipart. Это сохранило мое приложение.

1 голос
/ 11 января 2011

Что не так с простым определением URL-адреса Photo # как?

class Photo
  def url(*args)
    attachment.url(*args)
  end
end

Не нужно здесь фантазировать.

1 голос
/ 11 января 2011

Я бы рекомендовал заменить действие new на действие edit (вы можете автоматически создавать фотомодель, когда пользователь выбирает действие. Таким образом, вы можете использовать загрузку файла AJAX (поддерживается в некоторые современные браузеры) с резервной версией Flash для выполнения загрузки, а также для редактирования метаданных. Для выполнения загрузки попробуйте посмотреть plupload или uploadify .

0 голосов
/ 11 января 2011

По сути, вы разделяете создание объекта Photo на две части: загрузку фотографии и добавление метаданных. На не AJAX-сайте это будет два отдельных шага на двух отдельных страницах.

Что я хотел бы сделать, это разрешить загрузке AJAX создать экземпляр объекта Photo и сохранить его (вместе с загруженной фотографией). Затем я хотел бы, чтобы код AJAX возвращал на сайт токен, соответствующий переменной сеанса, чтобы форма знала, что запись для фотографии уже создана. Когда пользователь отправляет оставшуюся часть формы, если токен присутствует, он будет знать, как заполнить данные уже созданного фотообъекта. Если токен отсутствует, он будет знать, что ему нужно создать объект Photo с нуля.

...