J'ai des enregistrements qui, au lieu d'être supprimés, sont invalidés en créant une entrée dans une table polymorphe record_invalidations.Rails scope par absence d'association has_one polymorphique
La configuration ressemble à ceci:
class RecordInvalidation < ActiveRecord::Base
belongs_to :archivable, polymorphic: true
end
class Record < ActiveRecord::Base
has_one :invalidation, class_name: "RecordInvalidation", as: :archivable
def self.default_scope
where(invalidation: nil)
end
end
(Il y a plusieurs classes d'enregistrement, d'où la relation polymorphes.)
Question: Comment puis-je faire un champ d'application, qui renvoie les enregistrements en fonction de la absence des entrées d'une autre classe pointant vers la classe en question.
Le code actuel ne fonctionne pas car le pointeur de relation se trouve dans la table records_invalidations, pas dans la table d'enregistrements.
MISE À JOUR 2
La classe record_invalidation correspond au nom de la table très bien, je pense que le problème est le nom de la colonne. Voici le schéma (simplifié):
create_table "records", force: :cascade do |t|
t.text "content", null: false
end
create_table "record_invalidations", force: :cascade do |t|
t.integer "archivable_id"
t.string "archivable_type"
end
MISE À JOUR 3
Je vois savoir pourquoi la première erreur se produisait, alors j'ai enlevé cette mise à jour. Maintenant, je passe le nom de table correct que je rejoins dans la requête SQL, mais j'ai un certain nombre d'arguments incompatibles. Puis-je passer un autre argument à la clause where?
self.joins(:invalidation).where('record_invalidations.id is null')
donne:
ActiveRecord::StatementInvalid: PG::ProtocolViolation: ERROR: bind
message supplies 1 parameters, but prepared statement "a56" requires 2
: SELECT "records".* FROM "records"
INNER JOIN "record_invalidations" ON
"record_invalidations"."archivable_id" = "records"."id" AND
"record_invalidations"."archivable_type" = $1 WHERE
(record_invalidations.id is null) AND "plans"."id" = $2 LIMIT 1
Je ne peux pas vérifier ceci pour le moment d'où le commentaire, mais je pense que vous pouvez faire '.joins (: invalidation). Where ('invalidations.id is null')' ou similaire, laissez-moi savoir si cela fonctionne . –
Plus près! J'ai essayé: self.joins (: infirmation) .où ('invalidations.id est nulle) et a obtenu un très proche sortie de SQL, mais voir une erreur: ActiveRecord :: StatementInvalid: PG :: UndefinedTable: ERREUR : missing Entrée FROM-clause pour la table "invalidation" LINE 1: ... cord_invalidations "." archivable_type "= $ 1 OERE (invalidati ... ^ –
Pouvez-vous essayer' self.table_name = 'records'' (ou quel que soit le nom de la table) dans la classe RecordInvalidation? Peut-être que l'ancienne portée fonctionnerait - dans ce cas? –