Rails acts_as_paranoid - belongs_to不使用with_deleted

时间:2013-12-03 15:24:31

标签: ruby-on-rails belongs-to acts-as-paranoid

我有两个带有belongs_to - has_many关系的模型,您可以在下面看到(由于模型非常大,我只包含与此问题相关的代码部分):

product.rb

 class Product < ActiveRecord::Base
   attr_accessible :title, :description, [...]
   has_many :test_cycles
   acts_as_paranoid
 end


test_cycle.rb

 class TestCycle < ActiveRecord::Base
   belongs_to :product, with_deleted: true
   acts_as_paranoid
   delegate :title, to: :product, prefix: true
 end

根据Github上的自述文件(https://github.com/goncalossilva/acts_as_paranoid),这应该有效:

class Parent < ActiveRecord::Base
    has_many :children, :class_name => "ParanoiacChild"
end

class ParanoiacChild < ActiveRecord::Base
    belongs_to :parent
  belongs_to :parent_including_deleted, :class_name => "Parent", :with_deleted => true
  # You cannot name association *_with_deleted
end

parent = Parent.first
child = parent.children.create
parent.destroy

child.parent #=> nil
child.parent_including_deleted #=> Parent (it works!)

但是,如果我删除测试周期的父产品并尝试通过test_cycle.product访问它(假设存在test_cycle和product对象),则返回nil(即使with_deleted:true包含在模型!)。

如果我在与删除产品相同的test_cycle上调用test_cycle.product_title,它会运行查询“SELECT products。* FROM products WHERE productsid = 1 LIMIT 1“,我收到运行时错误: “RuntimeError:TestCycle#product_title委托给product.title,但产品为零”。

但是,如果我直接在数据库中运行查询,则会找到该产品(因为它并未真正删除,但只有acts_as_paranoid设置了deleted_at字段)。

因此,似乎忽略了产品模型中的'with_deleted:true'。知道为什么会这样吗?或者还有其他原因导致这不起作用吗?

我希望我能说清楚,如果没有,请问我,我很乐意提供更多信息。谢谢!

1 个答案:

答案 0 :(得分:1)

您还必须提供 foreign_key 。如果您看一下这些规格很明显,但文档不是最新的。

使用此代码:

class ParanoiacChild < ActiveRecord::Base
  belongs_to :parent
  belongs_to :parent_including_deleted, :class_name => "Parent", :foreign_key => "parent_id", :with_deleted => true
  # You cannot name association *_with_deleted
end

以下是规范中的摘录(参见:https://github.com/goncalossilva/acts_as_paranoid/blob/rails3.2/test/test_helper.rb):

class ParanoidHasManyDependant < ActiveRecord::Base
  acts_as_paranoid
  belongs_to :paranoid_time
  belongs_to :paranoid_time_with_deleted, :class_name => 'ParanoidTime', :foreign_key => :paranoid_time_id, :with_deleted => true
  belongs_to :paranoid_time_polymorphic_with_deleted, :class_name => 'ParanoidTime', :foreign_key => :paranoid_time_id, :polymorphic => true, :with_deleted => true

  belongs_to :paranoid_belongs_dependant, :dependent => :destroy
end