Rails 4: 在编辑视图表单中替换/删除上传的文件

Rails 4: replace / delete uploaded file in edit view form

一个similar question已经被问过了,但是答案只有Rails3,所以我冒昧地问一个新问题。

我有一个 Rails 4 应用程序,具有以下型号:

class User < ActiveRecord::Base
  has_many :administrations
  has_many :calendars, through: :administrations
end

class Calendar < ActiveRecord::Base
  has_many :administrations
  has_many :users, through: :administrations
  has_many: :posts
end

class Administration < ActiveRecord::Base
  belongs_to :user
  belongs_to :calendar
end

class Post < ActiveRecord::Base
  belongs_to :calendar
end

Post 模型具有以下属性:

references :calendar, index: true, foreign_key: true
date :date
time :time
string :subject
string :format
text :copy
attachment :image

并且附件在 Post 型号中使用 Paperclip 设置如下:

has_attached_file :image, styles: { small: "64x64", med: "100x100", large: "200x200" }
validates_attachment :image, :content_type => { :content_type => "image/png" },
                                :size => { :in => 0..3000.kilobytes }

image 添加到 Post 可以正常工作,通过以下 form:

<%= form_for [@calendar, @calendar.posts.build] do |f| %>
  <% if @post.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@post.errors.count, "error") %> prohibited this post from being saved:</h2>

      <ul>
      <% @post.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <p>
      <%= f.label :date %><br>
      <%= f.date_select :date %>
    </p>
    <p>
      <%= f.label :time %><br>
      <%= f.time_select :time %>
    </p>
    <p>
      <%= f.label :subject %><br>
      <%= f.text_field :subject %>
    </p>
    <p>
      <%= f.label :format %><br>
      <%= f.text_field :format %>
    </p>
    <p>
      <%= f.label :copy %><br>
      <%= f.text_area :copy %>
    </p>
    <p>
      <%= f.label :image %><br>
      <%= f.file_field :image %>
    </p>
  </div>

  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

查看附加到 Postimage 也运行良好,感谢此 show 视图:

<h2>Post from <%= @post.date.strftime("%A, %d") %></h2>

<div>
    <p><strong>Date</strong></p>
    <%= @post.date.strftime("%A, %d") %>
</div>
<div>
    <p><strong>Time</strong></p>
    <%= @post.time.strftime("%I:%M %p") %>
</div>
<div>
    <p><strong>Subject</strong></p>
    <%= @post.subject %>
    </div>
<div>
    <p><strong>Format</strong></p>
    <%= @post.format %>
    </div>
<div>
    <p><strong>Copy</strong></p>
    <%= @post.copy %>
</div>
<div>
    <p><strong>Image</strong></p>
    <%= image_tag @post.image.url(:med) %>
</div>

但是,当我转到 edit 视图时,对于我之前上传图片的 post,我只看到允许我添加图片的字段和一条消息说"no file chosen".

edit 视图使用(目前)与 new 视图相同的形式,如上所示。

我怎样才能实现以下目标:

  1. 让上传的图片出现在编辑页面。
  2. 允许用户删除此图像。
  3. 允许用户用新图像替换此图像。

–––––

更新:我找到了解决上面第 1 项的方法,方法是替换

<p>
  <%= f.label :image %><br>
  <%= f.file_field :image %>
</p>

<p>
  <%= f.label :image %><br>
    <% if @post.image.exists? %>
      <%= image_tag @post.image.url(:med) %>
    <% else %>
      <%= f.file_field :image %>
    <% end %>
</p>

在我的 Post edit 视图中。

我仍在处理第 2 项和第 3 项,绝对需要一些帮助。

–––––

如有必要,我很乐意分享更多代码。

有什么想法吗?

对于 #2 - 允许用户删除图像,您可能会发现这个 SO Issue helpful

或者,根据 Paperclip's documentation,您可以简单地创建一个虚拟复选框,然后在您的控制器的更新方法中,查看该复选框是否已被勾选并删除文档中提到的附件。

对于 #3 - 允许用户用新图像替换此图像

只需按照以下方式修改您的代码:

<p>
  <%= f.label :image %><br>
    <% if @post.image.exists? %>
      <%= image_tag @post.image.url(:med) %>
    <% end %>
    <%= f.file_field :image %>
</p>

这样,file_field 始终存在(允许用户替换或添加他们的图像)