Rails 3 Paperclip Uploadify: Сохраните загруженные вложения объекта перед сохранением объекта

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

# app/models/asset.rb
class Asset < ActiveRecord::Base
  # Nothing here yet
end

# app/models/image.rb
class Image < Asset
  belongs_to :assetable, :polymorphic => true
  has_attached_file :file, {
    :styles => {
      :small => { :geometry => '23x23#', :format => 'png' },
      :medium => { :geometry => '100x100#', :format => 'png' } } 
  }.merge(PAPERCLIP_STORAGE_OPTIONS).merge(PAPERCLIP_STORAGE_OPTIONS_ASSET_IMAGE) # Variables sent in environments to direct uploads to filesystem storage in development.rb and S3 in production.rb
  validates_attachment_presence :file
  validates_attachment_size :file, :less_than => 5.megabytes
end

Затем у меня есть другой тип объекта, Unit, к которому я прикрепляю несколько изображений следующим образом:

# app/models/unit.rb
class Unit < ActiveRecord::Base
  # ...

  has_many :images, :as => :assetable, :dependent => :destroy
  accepts_nested_attributes_for :images

end

# app/controllers/units_controller.rb
class UnitsController < ApplicationController
  # ...

  def new
    @unit = current_user.units.new
    # ...
    @unit.images.build
  end

  def create
    @unit = current_user.units.new(params[:unit])
    # ...
    respond_to do |format|
      if @unit.save
        format.html { redirect_to(@unit, :notice => 'Unit creation successful!') }
      else
        format.html { render :action => "new" }
      end
    end
  end

  def show
    @unit = current_user.units.find(params[:id])
    @unit_images = @unit.images
    # ...
  end

  def edit
    @unit = current_user.units.find(params[:id])
    # ...
    @unit.images.build
  end

  def update
    @unit = current_user.units.find(params[:id], :readonly => false)

    respond_to do |format|
      if @unit.update_attributes(params[:unit])
        format.html { redirect_to(@unit, :notice => 'Unit was successfully updated.') }
      else
        format.html { render :action => "edit" }
      end
    end
  end

  def destroy
    @unit = current_user.units.find(params[:id])
    @unit.destroy

    respond_to do |format|
      format.html { redirect_to(units_url) }
    end
  end

end

# app/views/units/_form.html.haml
.field # Display already uploaded images
  = f.fields_for :images do |assets|
    - unless assets.object.new_record?
      = link_to(image_tag(assets.object.file.url(:medium)), assets.object.file.url(:original))
.field # Display field to add new image
  = f.fields_for :images do |assets|
    - if assets.object.new_record?
      = assets.label :images, "Image File"
      = assets.file_field :file, :class => 'uploadify'

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

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

%script
  $(document).ready(function() {
    $('.uploadify').uploadify({
      uploader        : '/uploadify/uploadify.swf',
      cancelImg       : '/uploadify/cancel.png',
      auto            : true,
      multi           : true,
      script          : '#{units_path}',
      scriptData      : {
        "#{key = Rails.application.config.session_options[:key]}" : "#{cookies[key]}",
        "#{request_forgery_protection_token}" : "#{form_authenticity_token}",
      }
    });   
  });

Так что, хотя я могу легко загрузить с помощью скрепки, Uploadify не будет работать. Любая помощь приветствуется. Заранее спасибо.


ОБНОВЛЕНИЕ:

После дополнительных исследований я наткнулся на этот комментарий к аналогичной проблеме: Rails3, S3, Paperclip Attachment в качестве собственной модели?. Есть мысли о том, сработает ли это в данной ситуации? Есть ли простой способ определить unit.id из метода /new и передать его в объект, созданный с помощью Uploadify?


person theandym    schedule 22.03.2011    source источник


Ответы (1)


Однажды мы решили очень похожую проблему, сохранив модель сразу же при загрузке формы в состоянии draft (с использованием конечного автомата). Таким образом, модель доступна, когда вы пытаетесь прикрепить файлы, которые вы загружаете, и как только вы отправляете остальную часть формы, вы в основном просто обновляете модель, которая меняет ее состояние на, например, published. Обновить контроллеры и т. Д. Потребовалось немного, но это помогло.

person polarblau    schedule 22.03.2011
comment
Мне нравится такой подход, и я внедряю его. Однако что вы сделали с обязательными атрибутами при сохранении модели в состояние draft? Например, у меня есть несколько validates_presence_of утверждений, которые должны быть выполнены. Есть ли простой способ пропустить проверку? - person theandym; 22.03.2011
comment
Мы решили эту проблему, проверив только on update: validates_presence_of :foobar, :on => :update - person polarblau; 22.03.2011