Rails nom de classe / type ne fonctionne pas pour un has_many polymorphes: par
-
22-09-2019 - |
Question
J'ai un système de facturation qui gère les débits et crédits. Fondamentalement, le montant de la facture est obtenue par la somme de ses débits et le solde est calculé en prenant la somme de ses crédits et en soustrayant contre le montant total.
Je fais cela avec quatre modèles.
- Facture
- Ligne article
- Débit
- Crédit
Le fonctionnement se fait par un joint modèle (ligne d'objet) qui a une association polymorphique appelée enregistrement. Tout semble fonctionner correctement au premier coup d'œil. Toutefois, l'inspection de la poste montre que si le recordable_id apparaît bien, le recordable_type est nul.
Voici une ventilation du code:
class Invoice < ActiveRecord::Base
has_many :line_items, :dependent => :destroy
has_many :debits, :through => :line_items, :as => :recordable
has_many :credits, :through => :line_items, :as => :recordable
end
class LineItem < ActiveRecord::Base
belongs_to :invoice
belongs_to :recordable, :polymorphic => true
belongs_to :credit, :class_name => "Credit", :foreign_key => "recordable_id"
belongs_to :debit, :class_name => "Debit", :foreign_key => "recordable_id"
end
class Credit < ActiveRecord::Base
has_many :line_items, :as => :recordable, :dependent => :destroy
end
class Debit < ActiveRecord::Base
has_many :line_items, :as => :recordable, :dependent => :destroy
end
Quelqu'un peut-il me diriger dans la bonne direction ici?
La solution
Vous déclarez des associations ambigous sur votre classe LineItem
.
En un mot, belongs_to
fait dans votre classe:
-
belongs_to :invoice
crée uneinvoice
méthode qui recherche les factures table pour un enregistrement référencé parinvoice_id
-
belongs_to :recordable, :polymorphic => true
crée unerecordable
méthode qui recherche la tablerecordable_type.underscore.pluralize
pour un enregistrement référencé parrecordable_id
-
belongs_to :credit, :class_name => "Credit", :foreign_key => "recordable_id"
crée unecredit
méthode qui recherche par les crédits table pour un enregistrement référencé parrecordable_id
. Notez querecordable_type
est ignoré ici. - même pour
belongs_to :debit
respectivement.
Étant donné que votre LineItem ne peut appartenir soit à un crédit ou un débit, il n'a pas de sens de déclarer ces associations en plus. Vous pouvez vous référer à ces via l'association recordable
.
Autres conseils
Invoice.last.credits << Credit.new
Ceci est la façon correcte dans l'attribution des associations, je suis perplexe pourquoi le recordable_type
n'est pas repris.
Serrant à pailles ici, mais avez-vous essayé:
Invoice.last.credits << Credit.create(:value => 1, :date => Time.now, ...)
J'ai personnellement eu des problèmes lors de l'utilisation de plusieurs types de nombreux à plusieurs tables de jointure dans Rails, souvent résolus en utilisant le plugin de has_many_polymorphs
.
Désolé que cela ne répond pas directement à votre question.