回形针在更新时删除现有附件

paperclip removes existing attachment on update

AR 模型

class Post < ActiveRecord::Base
  has_one :sponsor
  accepts_nested_attributes_for :sponsor
end

class Sponsor < ActiveRecord::Base
  has_attached_file :logo
  belongs_to :post
end

控制器

def update
  if @post.update(post_params)
    flash[:success] = 'Post update sucessfully'
  else
    flash[:error] = @post.errors.full_messages.join(', ')
    render :edit
  end
end

def post_params
  params.require(:post).permit(:title, :content, sponsor_attributes: [:descriptive_text, :logo, :name, :website, :description])
end

此处,当 Post 更新时,赞助商也会以嵌套形式更新。

但是,如果用户没有选择任何图像,在更新时,Paperclip 会删除现有附件。

如果用户在更新记录时没有 select 其他附件,我们如何保留现有附件?

accepts_nested_attributes_for :sponsor, reject_if: :all_blank

reject_if.

你遇到的问题是,不幸的是,Paperclip 在接受数据方面实际上相当 "dumb"。

由于许多人向 Paperclip 发送关联数据,它基本上会根据所提供的内容构建对象。在您的情况下,这意味着您正在发送空白对象,导致 Paperclip 将您现有的附件替换为空白对象。

accepts_nested_attributes_forreject_if 开关解决了这个问题——它允许您指定 Rails 将 "reject" 任何嵌套数据的任何场合,保留你有文件...

reject_if

Allows you to specify a Proc or a Symbol pointing to a method that checks whether a record should be built for a certain attribute hash.

The hash is passed to the supplied Proc or the method and it should return either true or false. When no :reject_if is specified, a record will be built for all attribute hashes that do not have a _destroy value that evaluates to true.

Passing :all_blank instead of a Proc will create a proc that will reject a record where all the attributes are blank excluding any value for _destroy.


需要注意的是,如果您要更新图像之外的 其他(我看到您有 :descriptive_text:logo:name:website:description)。

在这种情况下,您需要将适当的数据传递给您的 Sponsor 模型(IE 没有 logo 参数):

def post_params
   sponsor_params = [:id, :descriptive_text, :logo, :name, :website, :description]
   sponsor_params -= [:logo] if (action_name == "update") && !params[:post][:sponsor_attributes][:logo]

   params.require(:post).permit(:title, :content, sponsor_attributes: sponsor_params)
end

我相信 Paperclip validators 有更好的方法来做到这一点,但现在以上应该足够了。


参考文献:

  • Preventing Paperclip from deleting/overwriting attachments on update
  • Rails with Paperclip ignore empty attachments