【问题标题】:CarrierWave not saving upload after form redisplay表单重新显示后 CarrierWave 不保存上传
【发布时间】:2012-04-04 17:58:38
【问题描述】:

我有一个 Rails 应用程序,它最初使用 Paperclip 进行文件上传,但是,当我看到 CarrierWave 显然在表单重新显示上具有“持久上传”类型的功能时,我决定尝试一下。

在我看来,我有以下几点:

= f.input :attachment
= f.hidden_field :attachment_cache

如果表单验证失败并重新显示,它会正确缓存文件,但是当我更正验证错误并重新提交时,附件不会被处理。

Started POST "/section/model" for 127.0.0.1 at 2012-03-20 08:51:56 +0000
  Processing by Client::WishesController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"zkdPQBsAnsNzx555rkwZ5+clfnLaXg+NtL+GdFei188=", "model"=>{"title"=>"Sample", "content"=>"Sample content", "contact_name"=>"Mr Sample", "contact_email"=>"sample@example.com", "attachment_cache"=>"20120320-0851-42559-1644/SampleAttachment.pdf"}, "commit"=>"Create Wish"}
  Client Load (0.3ms)  SELECT `clients`.* FROM `clients` WHERE `clients`.`id` = 1 LIMIT 1
   (0.2ms)  BEGIN
  SQL (0.4ms)  INSERT INTO `models` (`attachment`, `client_id`, `contact_email`, `contact_name`, `content`, `created_at`, `status`, `title`, `updated_at`, `upload_content_type`, `upload_file_name`, `upload_file_size`, `upload_updated_at`) VALUES (NULL, 1, 'sample@example.com', 'Mr Sample', 'Sample content', '2012-03-20 08:51:56', 'Unresolved', 'Sample', '2012-03-20 08:51:56', NULL, NULL, NULL, NULL)

它似乎通过 params 中的 attachment_cache 正确传递了附件,但它没有保存附件,因为它没有 params[:model][:attachment] 字段。

它没有说明载波部分的任何进一步步骤,以使上传在CarrierWave GitHub 上的表单重新显示中工作。

【问题讨论】:

  • 如果我使用批量分配创建/更新并设置单独的变量,它可以工作,但我想知道是否有办法在没有批量分配的情况下做到这一点?
  • 为此考虑opening a ticket
  • 你找到答案了吗?
  • 您还必须将字段名称添加到强参数

标签: ruby-on-rails ruby upload carrierwave


【解决方案1】:

这是一个有点老的问题,但是在我将 strong 参数添加到控制器后它对我有用,如下所示:

#controller
def object_params
  params.require(:object).permit(:attachment, :attachment_cache)
end

#view
<%= f.file_field :attachment %>
<%= f.hidden_field :attachment_cache %>

【讨论】:

    【解决方案2】:

    尝试填充 avatar_cache 的值,这样当验证失败时,它会被预先填充到表单中:

    = f.hidden_field :attachment_cache, :value => @model.attachment_cache
    

    @model 是您的模型的名称

    当多次重新加载同一个表单时(即验证多次失败时),这似乎对我有用。我认为他们在文档中忽略了这一点。

    【讨论】:

    • 您还必须将字段名称添加到强参数
    【解决方案3】:

    这将 100% 解决您的问题

    请看一下

    accepts_nested_attributes_for :avatars, allow_destroy: true, 
     reject_if: lambda { |avatar| avatar[:avatar].blank? and avatar[:avatar_cache].blank?}
    

    avatar[:avatar]avatar[:avatar_cache] 均为空白时,我们将拒绝头像

    【讨论】:

      【解决方案4】:

      原因是“变了?”检查,当验证错误时,我们在 #{model}_cache 字段中传递缓存文件,该字段不是数据库表列,因此它不会保存对象,因为从 AR 的角度来看没有任何变化。

      我通过在包含文件的模型中创建一个方法来完成这项工作: “数据”是列名

      def data_cache=(text)
        @changed_attributes.merge!("data" => nil)
        super
      end
      

      希望这会有所帮助。

      【讨论】:

      • 我编辑删除了这个答案的背景故事。答案应该回答问题,而不是包含无关信息。随时查看我的更改,欢迎使用 StackOverflow!
      【解决方案5】:

      对我来说,问题是我有

      accepts_nested_attributes_for :avatars, allow_destroy: true, reject_if: lambda { |avatar| avatar[:file].blank? }
      

      所以我拒绝了该文件,因为该文件不存在

      需要注意的是,文件本身不会持久化,而只是文件缓存。这就是为什么载波docs 建议:

      向用户显示文件已上传可能是个好主意,如果是图像,小缩略图将是一个很好的指示:

      【讨论】:

        【解决方案6】:

        补充@marko的答案:

        如果您使用 Active Admin,则需要将缓存文件添加到 permit_params 行。

        permit_params: :title, :file, :file_cache
        

        【讨论】:

          猜你喜欢
          • 2012-05-12
          • 2015-03-15
          • 2015-04-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-10-25
          • 2013-12-09
          • 1970-01-01
          相关资源
          最近更新 更多