如何在销毁图像的同时删除数据库中的记录?
尽管图片已被删除,但在_article_form.html.erb中提交勾选<%= p.check_box :_destroy %>
后,记录仍保留在数据库中。
更新
我做的是如下;
1.我上传了3个文件。例如,p.object.id
分别为1,2和3。它奏效了。
2.我勾选了1个文件(p.object.id
为1)进行销毁并提交。有效。 DB和图像中的记录都被删除了。显示其余图像(2个文件)
3.我勾选了1个文件(p.object.id
为2)进行销毁并提交。它不起作用。数据库中的记录和图片(p.object.id
为2)已删除,但由于某种原因,新记录(p.object.id
4 )已插入数据库...
\上传\ image_uploader.rb
class ImageUploader < CarrierWave::Uploader::Base
.
.
include CarrierWave::RMagick
storage :file
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
.
.
\模型\ article.rb
class Article < ActiveRecord::Base
.
.
has_many :photos, dependent: :destroy
accepts_nested_attributes_for :photos, reject_if: :all_blank, allow_destroy: true
validates :content, presence: true, length: { maximum: 140 }
validate :check_for_at_least_image
.
.
def build_images
(3 - self.photos.size).times {self.photos.build}
end
def check_for_at_least_image
errors.add(:image, "select at least one") if self.photos.size <= 0
end
end
\模型\ photo.rb
class Photo < ActiveRecord::Base
belongs_to :article
mount_uploader :image, ImageUploader
end
\控制器\ articles_controller.rb
class ArticlesController < ApplicationController
.
.
def edit
@article = Article.find(params[:id])
@article.build_images
end
def update
@article = Article.find(params[:id])
if @article.update(article_params)
redirect_to current_user
else
render 'edit'
end
end
def destroy #This is used for destroying @article, NOT photo
@article.destroy
redirect_to root_url
end
private
def article_params
params.require(:article).permit(:content, :category_id, photos_attributes: [:id, :article_id, :image, :image_cache, :_destroy])
end
.
.
end
\ view \ shared \ _article_form.html.erb
<%= form_for(@article) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<div class="field">
<%= f.fields_for :photos do |p| %>
<%= p.hidden_field :article_id %>
<div class="photo">
<% if p.object.image and p.object.image.file %>
<%= image_tag p.object.image.thumb.url %>
<%= p.hidden_field :image_cache if p.object.image_cache %>
<label><%= p.check_box :_destroy %>delete</label> #tick this check box
<% end %>
<%= p.file_field :image %>
</div>
<% end %>
<%= f.text_area :content, placeholder: "enter..." %>
</div>
<%= f.submit class: "btn btn-large btn-primary" %>
<% end %>
答案 0 :(得分:1)
如果你想从db和view中删除数据,那么我推荐这种方式...不使用accept_nested_attributes_for
只能在保存父对象后才能工作,并且会使用{{1属性设置为true / 1。
<强> 1。通过传递object.id给你的元素一个唯一的id 2.使用此object.id选择元素并使用js.erb将其删除,并在成功的同一页面上使用远程调用/ ajax
==========第一种方法(没有accept_nested_attributes-for)======================
---------使用远程方法调用(不设置_destroy)----------------
_destroy
在articles_controller.rb中
<%= form_for(@article) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<div class="field">
<%= f.fields_for :photos do |p| %>
<%= p.hidden_field :article_id %>
##here i added id field which i need to recognize using id
<div class="photo" id="photo_<%= p.id %>">
<% if p.object.image and p.object.image.file %>
<%= image_tag p.object.image.thumb.url %>
<%= p.hidden_field :image_cache if p.object.image_cache %>
##instead of checkbox,use link_to
##<label><%= p.check_box :_destroy %>delete</label> #tick this check box
<%= link_to "Delete", article_path(p),{:method => :delete,:remote=>true%>
</td>
<% end %>
<%= p.file_field :image %>
</div>
<% end %>
<%= f.text_area :content, placeholder: "enter..." %>
</div>
<%= f.submit class: "btn btn-large btn-primary" %>
<% end %>
在destroy.js.erb 中
==========第二种方法(使用接受嵌套属性)========================= = 你的jquery 因此,在将_destroy设置为1后,记录也将被rails删除,因为我们已使用_destroy属性将其标记为要销毁 def destroy
##first remove from db and then from view using id passed
@article=Artice.find params[:id]
@audio.destroy
respond_to do |format|
format.js
end
end
---------使用jquery删除图像并将对象标记为破坏,方法是将_destroy设置为1(使用_destroy将其设置为1)------- ##delete the image from your view using p.id with a slideup animation(if needed)
$("#photo_<%= params[:id] %").slideUp("slow", function() { $('#photo_<%= params[:id]%>').remove();});
<%= form_for(@article) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<div class="field">
<%= f.fields_for :photos do |p| %>
<%= p.hidden_field :article_id %>
<div class="photo">
<% if p.object.image and p.object.image.file %>
<%= image_tag p.object.image.thumb.url %>
<%= p.hidden_field :image_cache if p.object.image_cache %>
##on click of checkbox,set _destroy to 1,which will get deleted by parent
##when parent is updated/saved
<label><%= p.check_box :_destroy :class => 'delete_member', :p_id => p.id %>
delete</label> #tick this check box
</td>
<% end %>
<%= p.file_field :image %>
</div>
<% end %>
<%= f.text_area :content, placeholder: "enter..." %>
</div>
<%= f.submit class: "btn btn-large btn-primary" %>
<% end %>
答案 1 :(得分:0)
dependent: :destroy
如果你破坏了一篇应该破坏照片的文章应该可行。如果这有问题,您可以随时创建回调“before_destroy
”或“after_destroy
”。
答案 2 :(得分:0)
您可以尝试将_destroy
重命名为remove_file
或remove_<mounted-point>
如果要手动删除文件,可以调用remove_<mounted-point>!
,然后保存对象(或在回调中执行)。
photo.remove_<mounted-point>!
photo.save