Reputation: 1887
I have Payment, Invoice, and Transaction models setup like this:
# transaction.rb
class Transaction < ActiveRecord::Base
belongs_to :customer
belongs_to :transactionable, polymorphic: true
end
# payment.rb
class Payment < ActiveRecord::Base
belongs_to :customer
has_many :transactions, as: :transactionable
end
# invoice.rb
class Invoice < ActiveRecord::Base
belongs_to :customer
has_many :transactions, as: :transactionable
end
In my customers show template, I'm finding all transactions that belong to the requested customer. I want to sort the the transactions by the date of the Invoice or Payment that they belong to. What is the best way to accomplish this?
class CustomersController < ApplicationController
def show
@customer = Customer.find(params[:id])
# I want the transactions sorted by the date of the Invoice or Payment they belong to
@transactions = Transaction.where(customer: @customer)
end
end
Upvotes: 2
Views: 103
Reputation: 9586
It may be possible with scopes.
You should be able to do something like the following:
transactions = Transaction.all
transactions = transactions.order_by_payment_date
transactions = transactions.order_by_invoice_date
transactions = transactions.includes_transactionable
transactions.each do |transaction|
# do what you want with the transaction and transactable
end
Hopefully this code just works:
class Transaction < ActiveRecord::Base
belongs_to :customer
belongs_to :transactionable, polymorphic: true
scope :includes_transactionable, -> { includes(:transactionable) }
scope :order_by_payment_date, -> {
# This may or may not work, you may need to specify a has_many
# relationship to Payment, or do more to get the join to work
joins(Payment.arel_table).merge( Payment.descending )
}
scope :order_by_invoice_date, -> {
# This may or may not work, you may need to specify a has_many
# relationship to Invoice, or do more to get the join to work
joins(Invoice.arel_table).merge( Invoice.descending )
}
end
class Payment < ActiveRecord::Base
belongs_to :customer
has_many :transactions, as: :transactionable
scope :descending, -> { order(arel_table[:payment_date].desc) }
end
class Invoice < ActiveRecord::Base
belongs_to :customer
has_many :transactions, as: :transactionable
scope :descending, -> { order(arel_table[:invoice_date].desc) }
end
Upvotes: 2
Reputation: 1854
If a transaction is always created alongside a payment or invoice, you could use the created_at
timestamp on the transactions table. If not however, in an effort to keep the transaction model from specifically knowing which models it can belong to, a good option would be to create another datetime column on the transactions table, and have it be updated with whatever datetime is most relevant in the associated object.
Upvotes: 1