【问题标题】:Problems with Destroy and Delete functions Rails销毁和删除函数的问题 Rails
【发布时间】:2016-04-27 20:13:43
【问题描述】:

我决定将我的应用程序上的销毁功能更改为仅将状态字段切换为 false(索引和显示操作仅显示状态为 true 的结果)。

好吧,我已经改变了这一点,一开始它可以工作,但现在它只是在完成提交之前“回滚”......

控制器销毁:

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 方法仅限于管理员(这是正确的方法吗?为什么不删除?)

谢谢!

【问题讨论】:

  • 你可以使用 paranoia gem 来实现这个功能
  • update_attributes(...) 更改为 update_attributes!(...) 并重试。 update_attributes! 会在更新失败时引发异常。该异常会告诉您更新失败的原因(通常是验证失败)。
  • 不,它不正确,它完全不好!你的数据库关联是什么?
  • 不是为了打败一匹死马,而是覆盖删除功能感觉就像是代码味道。如果您想要软删除,我会查看 paranoid gem 或至少使用更恰当命名的方法。

标签: ruby-on-rails ruby destroy


【解决方案1】:

您的回滚问题可能与验证失败有关。你可以通过将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 不会做这个通过,这是他们之间的主要区别。

通过将其添加到上述关系中,您可以将控制器更改为:

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。 它允许您使用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)

无需覆盖或限制删除或销毁。

【讨论】:

  • 好的!这种方式看起来确实更值得信赖和安全地进行软删除。谢谢!!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-06-13
  • 1970-01-01
  • 2014-05-10
  • 2015-05-15
  • 2015-06-01
  • 2015-06-19
  • 1970-01-01
相关资源
最近更新 更多