Paranoia Gem - объединяет удаленные элементы

Я использую драгоценный камень Паранойи и сейчас борюсь с проблемой. Мне нужно присоединиться has_many удаленные элементы, но он возвращает не только удаленные. Мои модели:

class Mailing < ActiveRecord::Base

  acts_as_paranoid

  has_many :mailing_fields
  has_many :fields, through: :mailing_fields

end

class MailingField < ActiveRecord::

  belongs_to :mailing
  belongs_to :field

end

class Field < ActiveRecord::Base

  has_many :mailing_fields, dependent: :destroy
  has_many :mailings, through: :mailing_fields

end

Я запускаю запрос, который должен вернуться mailings с удаленными элементами:

Field.joins(:mailings).where('mailings.id = ?', mailing_id)

6 ответов

Решение

Параноидальный драгоценный камень имеет встроенную область для доступа к удаленным элементам: with_deleted.

Mailing.with_deleted.joins(:fields).where(id: mailing_id)

Единственное работающее решение, которое я нашел, это вручную указать JOIN:

Field.joins('INNER JOIN "mailings" ON "mailings"."id" = "fields"."mailing_id"')
     .where('mailings.id = ?', mailing_id)

unscopedтакже принимает блок, поэтому вы можете сделать следующее:

      Mailing.unscoped do
  Field.joins(:mailings).where('mailings.id = ?', mailing_id)
end

См.: https://api.rubyonrails.org/classes/ActiveRecord/Scoping/Default/ClassMethods.html#method-i-unscoped .

Вы можете удалить область в вашем запросе следующим образом:

Field.joins(:mailings).where("mailings.deleted_at != :deleted_status OR mailings.deleted_at = :deleted_status", deleted_status: nil).where(mailings: { id: mailing_id })

ИЛИ, так как вы пытаетесь получить Field которая, кажется, имеет отношение многие ко многим, я бы предпочел инвертировать запрос как таковой:

Mailing.unscoped.joins(:fields).find(mailing_id).fields

Дайте мне знать, смогу ли я помочь.

paranoid gem устанавливает область по умолчанию, включающую только не удаленные элементы в запросы. Обходной путь будет:

Field.joins(:mailings).where('mailings.id = ? mailings.deleted_at != ?', mailing_id, nil)

Я могу опоздать на вечеринку, но это может помочь, если кто-то наткнется на эту проблему.

Вы можете создать дополнительную связь между родительским и дочерним объектами, чтобы также включить удаленные записи.

В контексте заданного вопроса

class Field < ActiveRecord::Base
  has_many :mailing_fields, dependent: :destroy
  has_many :mailing_fields_with_deleted, -> { with_deleted }
 
  has_many :mailings, through: :mailing_fields
  has_many :mailings_with_deleted, through: :mailing_fields_with_deleted
end

а затем используйте это соотношение:Field.joins(:mailings_with_deleted).where('mailings.id = ?', mailing_id)

Другие вопросы по тегам