Destroy 和 Delete 函数的问题 Rails
Problems with Destroy and Delete functions Rails
我决定更改我应用程序上的销毁功能,将状态字段切换为 false(索引和显示操作仅显示状态为 true 的结果)。
好吧,我已经改变了这个,一开始它起作用了,但现在它只需要 "rolling back" 就可以完成提交...
控制器销毁:
def destroy
@customer = Customer.find(params[:id])
@contact = @customer.contacts
@adress = @customer.adresses
if @customer.delete(current_user)
@contact.each do |f|
f.delete(current_user)
end
@adress.each do |g|
@telephone = g.telephones
@telephone.each do |t|
t.delete(current_user)
end
g.delete(current_user)
end
flash[:success] = "Cliente excluído"
else
flash[:danger] = "Erro! O cliente não foi excluído."
end
redirect_to customers_path
end
模型删除:
def delete(user_id)
update_attributes(status: false, changed_by: user_id, deleted_at: Time.now, updated_at: Time.now)
end
除此之外,我将 :destroy 方法限制为管理员(这是正确的方法吗?为什么不删除?)
谢谢!
您的回滚问题可能与验证失败有关。您可以通过将 update_attributes
更改为 update_attributes!
来找出这是什么,这将在验证失败时抛出错误,您可以看到哪里出了问题。
除此之外,您还可以通过多种方式改进代码
首先,您可以添加 dependent: :destroy 到关系中,而不是手动删除客户的联系人和地址。
这是这样工作的:
class Customer < ActiveRecord::Base
has_many :contacts, dependent: :destroy
has_many :adresses, dependent: :destroy
end
class Adress < ActiveRecord::Base
has_many :telephones, dependent: :destroy
end
当您在记录上调用 .destroy
时,它会在任何依赖于它们的关系上调用 .destroy
::destroy。 .delete
不会做这个pass through,这是他们最大的区别。
通过将其添加到上述关系中,您可以将控制器更改为:
def destroy
@customer = Customer.find(params[:id])
if @customer.destroy
flash[:success] = "Cliente excluído"
else
flash[:danger] = "Erro! O cliente não foi excluído."
end
redirect_to customers_path
end
这将破坏客户、它的地址和地址的电话。
非永久删除
要像您希望的那样进行软删除,您应该使用 Paranoia gem。
它允许您将 class 分配给 acts_as_paranoid
,因此当您调用 .delete
或 .destroy
时,它并没有真正被删除,它只是隐藏起来,以后可以恢复。
它与 Activerecord 完美集成,因此您无需执行 Customer.where(status: true)
之类的操作来获取未删除的记录,默认情况下它不会包含已删除的记录。尽管您可以根据需要提出要求。
gem 的 Github 页面很好地解释了如何使用它。
默认情况下,它不会保存执行删除的用户,只保存执行删除的时间。如果你想这样做,你应该创建一个包装器,在分配执行删除的用户后调用 delete。
像这样的东西应该可以工作:
def destroy_by(user)
update_attributes!(changed_by: user)
destroy
end
然后你可以将控制器中的 @customer.destroy
更改为 @customer.destroy_by(current_user)
无需覆盖或限制删除或销毁。
我决定更改我应用程序上的销毁功能,将状态字段切换为 false(索引和显示操作仅显示状态为 true 的结果)。
好吧,我已经改变了这个,一开始它起作用了,但现在它只需要 "rolling back" 就可以完成提交...
控制器销毁:
def destroy
@customer = Customer.find(params[:id])
@contact = @customer.contacts
@adress = @customer.adresses
if @customer.delete(current_user)
@contact.each do |f|
f.delete(current_user)
end
@adress.each do |g|
@telephone = g.telephones
@telephone.each do |t|
t.delete(current_user)
end
g.delete(current_user)
end
flash[:success] = "Cliente excluído"
else
flash[:danger] = "Erro! O cliente não foi excluído."
end
redirect_to customers_path
end
模型删除:
def delete(user_id)
update_attributes(status: false, changed_by: user_id, deleted_at: Time.now, updated_at: Time.now)
end
除此之外,我将 :destroy 方法限制为管理员(这是正确的方法吗?为什么不删除?)
谢谢!
您的回滚问题可能与验证失败有关。您可以通过将 update_attributes
更改为 update_attributes!
来找出这是什么,这将在验证失败时抛出错误,您可以看到哪里出了问题。
除此之外,您还可以通过多种方式改进代码
首先,您可以添加 dependent: :destroy 到关系中,而不是手动删除客户的联系人和地址。
这是这样工作的:
class Customer < ActiveRecord::Base
has_many :contacts, dependent: :destroy
has_many :adresses, dependent: :destroy
end
class Adress < ActiveRecord::Base
has_many :telephones, dependent: :destroy
end
当您在记录上调用 .destroy
时,它会在任何依赖于它们的关系上调用 .destroy
::destroy。 .delete
不会做这个pass through,这是他们最大的区别。
通过将其添加到上述关系中,您可以将控制器更改为:
def destroy
@customer = Customer.find(params[:id])
if @customer.destroy
flash[:success] = "Cliente excluído"
else
flash[:danger] = "Erro! O cliente não foi excluído."
end
redirect_to customers_path
end
这将破坏客户、它的地址和地址的电话。
非永久删除
要像您希望的那样进行软删除,您应该使用 Paranoia gem。
它允许您将 class 分配给 acts_as_paranoid
,因此当您调用 .delete
或 .destroy
时,它并没有真正被删除,它只是隐藏起来,以后可以恢复。
它与 Activerecord 完美集成,因此您无需执行 Customer.where(status: true)
之类的操作来获取未删除的记录,默认情况下它不会包含已删除的记录。尽管您可以根据需要提出要求。
gem 的 Github 页面很好地解释了如何使用它。
默认情况下,它不会保存执行删除的用户,只保存执行删除的时间。如果你想这样做,你应该创建一个包装器,在分配执行删除的用户后调用 delete。
像这样的东西应该可以工作:
def destroy_by(user)
update_attributes!(changed_by: user)
destroy
end
然后你可以将控制器中的 @customer.destroy
更改为 @customer.destroy_by(current_user)
无需覆盖或限制删除或销毁。