Nome/tipo da classe Rails não funciona para um has_many polimórfico: através de
-
22-09-2019 - |
Pergunta
Eu tenho um sistema de faturamento que gerencia débitos e créditos. Basicamente, o valor da fatura é obtido pela soma de seus débitos e o saldo é derivado pegando a soma de seus créditos e subtraindo -o contra o valor total.
Estou fazendo isso com quatro modelos.
- Fatura
- Item da linha
- Débito
- Crédito
A maneira como funciona é através de um modelo de junção (item de linha) que possui uma associação polimórfica chamada Grandable. Tudo parece funcionar corretamente à primeira vista. No entanto, a inspeção do item de linha mostra que, embora o registro_ID apareça tudo bem, o gravável_type é nulo.
Aqui está uma quebra do código:
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
Alguém pode me apontar para a direção certa aqui?
Solução
Você está declarando associações ambigóticas em seu LineItem
classe.
Em poucas palavras, belongs_to
Faz isso em sua classe:
belongs_to :invoice
cria um métodoinvoice
que pesquisa o faturas Tabela para um registro referenciado porinvoice_id
belongs_to :recordable, :polymorphic => true
cria um métodorecordable
que pesquisa orecordable_type.underscore.pluralize
Tabela para um registro referenciado porrecordable_id
belongs_to :credit, :class_name => "Credit", :foreign_key => "recordable_id"
cria um métodocredit
que pesquisam através do Créditos Tabela para um registro referenciado porrecordable_id
. Observe querecordable_type
é ignorado aqui.- O mesmo se aplica a
belongs_to :debit
respectivamente.
Já que seu lineitem só pode pertencer a um crédito ou Um débito que não faz sentido declarar essas associações adicionalmente. Você pode se referir a eles através do recordable
Associação.
Outras dicas
Invoice.last.credits << Credit.New
Esta é a maneira correta em atribuir associações a eu sou perplexo com o motivo pelo qual o recordable_type
não está sendo recolhido.
Segurando os canudos aqui, mas você já tentou:
Invoice.last.credits << Credit.create(:value => 1, :date => Time.now, ...)
Eu pessoalmente tive problemas ao usar tabelas de junta muitos para muitos do tipo, o que era frequentemente resolvido usando o has_many_polymorphs
plugar.
Desculpe que isso não responda diretamente à sua pergunta.