I have payments with one transaction associated with each payment. The transactions can be associated with payments, deposits, etc. so I need a :through relation.
The Payment class:
class Payment < ActiveRecord::Base
has_many :payment_transactions
has_many :transactions, :through => :payment_transactions
end
And the Transaction class:
class Transaction < ActiveRecord::Base
has_one :payment_transaction, :inverse_of => :transaction
has_one :payment, :through => :payment_transaction
end
And finally the PaymentTransaction class:
class PaymentTransaction < ActiveRecord::Base
belongs_to :payment
belongs_to :transaction
end
When adding the transaction to the payment I would like to be able to access the parent information (the payment attributes) from within the newly created transaction:
2.1.0 :001 > p = Payment.new
=> #<Payment id: nil, state: "new", created_at: nil, updated_at: nil>
2.1.0 :002 > p.save
=> true
2.1.0 :003 > p.transactions.build()
=> #<Transaction id: nil, myid: nil, parent_class_is: nil, created_at: nil, updated_at: nil>
2.1.0 :004 > p.transactions.first.payment
=> nil
I am looking for a way to access the payment from the newly created transaction associated with the payment - but no luck. The payment is saved, however the transaction is still not committed to the database. Only when the payment is saved and the associated transaction is stored I get access to the parent object:
2.1.0 :005 > p.save
2.1.0 :008 > p.reload
2.1.0 :009 > p.transactions.first.payment
=> #<Payment id: 3, state: "new", created_at: "2014-01-28 09:23:13", updated_at: "2014-01-28 09:23:13">
Using the :inverse_of is not possible with :through associations. :(
Edit 1:
Tried to access the parent via a proxy association:
app/concerns/transaction_proxy.rb
module TransactionProxy
private
def my_owner
proxy_association.owner
end
end
The payment model:
has_many :payment_transactions
has_many :transactions, -> { extending TransactionProxy }, :through => :payment_transactions
Loading the payment:
2.1.0 :006 > p = Payment.first
Payment Load (0.2ms) SELECT "payments".* FROM "payments" ORDER BY "payments"."id" ASC LIMIT 1
=> #<Payment id: 1, state: "new", created_at: "2014-01-28 12:31:11", updated_at: "2014-01-28 12:31:11">
Setting the transaction:
2.1.0 :007 > p.transactions.build()
=> #<Transaction id: nil, myid: nil, parent_class_is: nil, created_at: nil, updated_at: nil>
Query the transaction:
2.1.0 :005 > p.transactions.first
=> #<Transaction id: nil, myid: nil, parent_class_is: nil, created_at: nil, updated_at: nil>
2.1.0 :007 > p.transactions.first.payment
=> nil
and trying to use the proxy:
2.1.0 :006 > p.transactions.first.my_owner
NoMethodError: undefined method `my_owner' for #<Transaction:0x00000103e44450>
I assume that the .my_owner on a transaction should return the owner (payment) of that transaction?