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
Controller
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
这里,当更新帖子
时,赞助商也会以嵌套形式更新。
但是在更新时,如果用户未选择任何图像,Paperclip 会删除现有附件。
如果用户在更新记录时没有选择其他附件,我们如何保留现有附件?
最佳答案
accepts_nested_attributes_for :sponsor, reject_if: :all_blank
不幸的是,你遇到的问题是,Paperclip 在接受数据方面实际上相当“愚蠢”。
当许多人将关联数据发送到 Paperclip 时,它基本上会获取所提供的数据并从中构建对象。就您而言,这意味着您正在发送空白对象,导致回形针将您现有的附件替换为空白对象。
accepts_nested_attributes_for
的 reject_if
开关可以解决此问题 - 它允许您指定 Rails 将“拒绝”任何嵌套数据的任何情况,从而保留您所选择的文件。有...
reject_if
Allows you to specify a
Proc
or aSymbol
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 aProc
will create a proc that will reject a record where all the attributes are blank excluding any value for_destroy
.
需要注意的是,如果您要更新图像以外的内容(我看到您有 :descriptive_text
、:logo
、 :名称
,:网站
,:描述
)。
在这种情况下,您需要将适当的数据传递给您的 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来做到这一点,但目前以上应该足够了。
引用文献:
关于ruby-on-rails - 回形针在更新时删除现有附件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33253190/