Rails class name/type not working for a polymorphic has_many :through
I have an invoicing system that manages debits and credits. Basically the invoice amount is obtained by the sum of its debits and the balance is derived by taking the sum of its credits and subtracting it against the total amount.
I'm doing this with four models.
- Invoice
- Line Item
- Debit
- Credit
The way it works is via a join model (Line Item) that has a polymorphic association called recordable. Everything appears to work properly at first glance. However, inspecting the line item shows that while the recordable_id shows up alright, the recordable_type is nil.
Here is a break down of the code:
class Invoice < ActiveRecord::Base
has_many :line_items, :dependent => :destroy
has_many :debits, :through => :line_items, :as => :recordable
has_many :credits, :through =&开发者_Python百科gt; :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
Can anyone point me into the right direction here?
You are declaring ambigous associations on your LineItem
class.
In a nutshell, belongs_to
does this in your class:
belongs_to :invoice
creates a methodinvoice
which searches the invoices table for a record referenced byinvoice_id
belongs_to :recordable, :polymorphic => true
creates a methodrecordable
which searches therecordable_type.underscore.pluralize
table for a record referenced byrecordable_id
belongs_to :credit, :class_name => "Credit", :foreign_key => "recordable_id"
creates a methodcredit
which searches through the credits table for a record referenced byrecordable_id
. Note, thatrecordable_type
is ignored here.- same applies to
belongs_to :debit
respectively.
Since your LineItem may only belong to either a Credit or a Debit it makes no sense to declare these associations additionally. You can refer to these via the recordable
association.
Invoice.last.credits << Credit.new
This is the correct way in assigning associations to I am stumped as to why the recordable_type
is not being picked up.
Clutching at straws here but have you tried:
Invoice.last.credits << Credit.create(:value => 1, :date => Time.now, ...)
I've personally had issues when using multi-type many-to-many join tables in Rails, which was often resolved by using the has_many_polymorphs
plugin.
Sorry that this does not directly answer your question.
精彩评论