验证失败后,Carrierwave缓存的图像未被存储 - 嵌套表单

时间:2017-08-08 10:23:45

标签: ruby-on-rails validation carrierwave

我花了至少两天时间试图解决这个问题,过去几周我真的可以做一点方向,因为我觉得我已经完成了这里和其他地方列出的所有类似问题。

我使用模型关联和嵌套表单进行图像上传的Carrierwave设置,它工作正常。可以上载和更新图像。当我更改Post上的图像并导致表单验证失败时,设置图像缓存值(通过我添加到PostMediaUpload中的 upload_filename_cache =(text)方法确认),缓存值被放置在表单上的隐藏字段内,文件存储在tmp目录中。

当我使用传递验证重新提交表单时,缓存值似乎没有发生任何事情 - 没有错误,旧图像仍然存在。我试图尽可能多地包含信息。我希望这很简单,因为除了上传缓存版本的最后一步之外,一切似乎都按预期工作。

以下是我的模型的简化版本:

发布

has_one :post_media_upload, :dependent => :destroy

accepts_nested_attributes_for :post_media_upload, \
    :reject_if => proc {|attributes| attributes['upload_filename'].blank? \
    && attributes['upload_filename_cache'].blank?}

发布媒体上传

class PostMediaUpload < ApplicationRecord

  belongs_to :post

  mount_uploader :upload_filename, PostImageUploader

  validate :file_size_check

  def upload_filename_cache=(text)

    if upload_filename_cache
      byebug
      # TODO: We have a cached file, it exists in the hidden form field and the tmp/uploads folder
      # On successful form validation, the cached version isn't uploaded to S3 / set to upload_filename.
      #upload_filename = nil
      #changed_attributes.merge!("upload_filename" => nil)
    end

    super
  end

  private

    def file_size_check
      if upload_filename.size > 5.megabytes
        errors.add(:file_size, "should be less than 5MB")
      end
    end

end

发布媒体上传模式

create_table "post_media_uploads", force: :cascade do |t|
        t.integer  "post_id",        null: false
        t.string   "upload_filename",   null: false
        t.string   "original_filename", null: false
        t.string   "media_type",        null: false
        t.integer  "file_size",         null: false
        t.datetime "created_at",        null: false
        t.datetime "updated_at",        null: false
        t.index ["post_id"], name: "index_post_media_uploads_on_post_id", using: :btree
      end

PostImageUploader

class PostImageUploader < CarrierWave::Uploader::Base

  include CarrierWave::MiniMagick

  # Save Original File Name
  before :cache, :save_original_filename_and_data

  storage :fog

  def store_dir
    "uploads/posts/#{model.post_id}"
  end

  # Alter File Name to be Unique
  def filename
    "#{secure_token}.#{file.extension}" if original_filename.present?
  end

  # White list of extensions which are allowed to be uploaded.
  def extension_white_list
    %w(jpg jpeg png)
  end

  def fog_public
    false
  end

  def fog_authenticated_url_expiration
    5.minutes # in seconds from now,  (default is 10.minutes)
  end

  version :large do
    process resize_to_limit: [800, 800]
  end

  version :medium, :from_version => :large do
    process resize_to_limit: [500, 500]
  end

  version :thumb, :from_version => :medium do
    process resize_to_fit: [100, 100]
  end

  version :square do
    process :resize_to_fit => [300, nil]
  end

  protected
    def save_original_filename_and_data(file)
      model.original_filename ||= file.original_filename if file.respond_to?(:original_filename)
      model.media_type = file.content_type
      model.file_size = file.size
    end

    def secure_token
      var = :"@#{mounted_as}_secure_token"
      model.instance_variable_get(var) or model.instance_variable_set(var, Digest::SHA1.hexdigest([Time.now, rand].join))
    end

end

发布表单

<%= f.fields_for :post_media_upload do |h| %>
  Browse&hellip; <%= h.file_field :upload_filename, :multiple => false, :style => "display: none;", :onchange => "validateImageUpload(this);" %>
  <%= h.hidden_field :upload_filename_cache, :value => post.post_media_upload.upload_filename_cache %>
<% end %>

发布白色列表的Params

def post_params

  params.require(:post).permit(:title, ..omitted..
                     :is_private, post_media_upload_attributes: [:id, :post_id, :upload_filename, :upload_filename_cache] )

end

发布更新操作

if @post.update(post_params)
    @post.set_pending_changes
    redirect_to account_post_path(@post), notice: 'Your post was updated successfully'
else
    # Build Nested Resource if not present
    @post.build_post_media_upload unless @post.post_media_upload.present?
    render :edit
end

提前谢谢!

0 个答案:

没有答案