Rails act_as_paranoid - принадлежит_ не работает с with_deleted
У меня есть две модели с отношением own_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
Согласно Readme на 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, и объект продукта), он возвращает nil (даже если with_deleted: true включено в модель!),
Если я вызываю test_cycle.product_title в том же test_cycle с удаленным продуктом, он запускает запрос "SELECT products
.* ОТ products
ГДЕ products
,id
= 1 LIMIT 1", и я получаю ошибку времени выполнения:
"RuntimeError: TestCycle#product_title делегирован product.title, но product is nil".
Если я, однако, выполню запрос непосредственно в базе данных, продукт будет найден (поскольку он на самом деле не удален, а имеет только поле delete_at, установленное Act_as_paranoid).
Таким образом, кажется, что with_deleted: true в модели продукта игнорируется. Есть идеи, почему это происходит? Или может быть какая-то другая причина, почему это не работает?
Надеюсь, я проясню, если нет, пожалуйста, спросите, и я с радостью предоставлю больше информации. Спасибо!
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