Question

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.

  1. Invoice
  2. Line Item
  3. Debit
  4. 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 => :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?

Was it helpful?

Solution

You are declaring ambigous associations on your LineItem class.

In a nutshell, belongs_to does this in your class:

  1. belongs_to :invoice creates a method invoice which searches the invoices table for a record referenced by invoice_id
  2. belongs_to :recordable, :polymorphic => true creates a method recordable which searches the recordable_type.underscore.pluralize table for a record referenced by recordable_id
  3. belongs_to :credit, :class_name => "Credit", :foreign_key => "recordable_id" creates a method credit which searches through the credits table for a record referenced by recordable_id. Note, that recordable_type is ignored here.
  4. 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.

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top