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
Другие вопросы по тегам