Rails 4:以编辑视图形式替换/删除上传的文件

Posted

技术标签:

【中文标题】Rails 4:以编辑视图形式替换/删除上传的文件【英文标题】:Rails 4: replace / delete uploaded file in edit view form 【发布时间】:2015-12-30 22:49:06 【问题描述】:

已经问过similar question,但答案仅适用于 Rails 3,所以我冒昧地提出一个新问题。

我有一个 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 

通过以下formimage 添加到Post 可以正常工作:

<%= 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 视图时,对于我之前上传过图片的帖子,我只看到允许我添加图片的字段和一条消息“未选择文件”。

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

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

    让上传的图片出现在编辑页面中。 允许用户删除此图片。 允许用户将此图片替换为新图片。

–––––

更新:我找到了解决上述第 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,并且肯定可以在这些方面使用一些帮助。

–––––

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

有什么想法吗?

【问题讨论】:

【参考方案1】:

对于#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 始终存在(允许用户替换或添加他们的图像)

【讨论】:

谢谢美女亚历山大。对于#3,事情就像你的代码的魅力一样。但是,对于#2,我不确定我应该如何实现它。如有必要,我将继续挖掘并更新问题。 我是既成事实!我会用另一种方式编辑我的答案。 冻糕。我理解创建复选框背后的想法。我宁愿有一个小的“x”按钮,用户点击后图像就会消失,即使它没有立即删除(只有在保存帖子时才删除)。那需要一些 JS,对吧? 你总是可以在你的 post_controller 中创建一个调用 delete_image 函数的路由,并有一个 link_to 对该路由进行 ajax 调用,并在它执行后做一些漂亮的 javascript 太棒了,非常感谢您所做的一切。 Bonne journée à Gatineau(我在渥太华住了一年)。

以上是关于Rails 4:以编辑视图形式替换/删除上传的文件的主要内容,如果未能解决你的问题,请参考以下文章

无法在视图中显示或检索文件,该文件以路径的形式上传到数据库中。 (使用 laravel )

如何构建 Rails 视图以编辑关联的数据集

Rails 4:如何使用 AJAX 上传文件

如何使用Paperclip在Rails 4中上传多个图像

linux操作之文本编辑器

通过邮递员通过 API 使用 Rails 主动存储上传文件(.pdf、.jpg 等)? (不通过 Rails 视图)