Hi all,
Does anyone know how to run a find where a condition is based on an
attribute specified in an object’s model? I have a Payment object,
and in its model I have a function called “amount_unapplied”. That
code is:
Return the amount of the payment that has been applied to invoices
def amount_applied
return self.splits.sum(:amount) == nil ? 0 :
self.splits.sum(:amount)
end
In one of my controller methods, I have to return all of the Payment
records where amount_unapplied > 0. If I specify it as one of
the :conditions in a find, such as:
pmts = Payment.find(:all, :conditions => amount_unapplied > 0)
I get an “undefined local variable or method `amount_unapplied’”
exception, as there is no actual column called amount_unapplied…
Any ideas? Thanks!
Neal L wrote:
Hi all,
Does anyone know how to run a find where a condition is based on an
attribute specified in an object’s model? I have a Payment object,
and in its model I have a function called “amount_unapplied”. That
code is:
Return the amount of the payment that has been applied to invoices
def amount_applied
return self.splits.sum(:amount) == nil ? 0 :
self.splits.sum(:amount)
end
In one of my controller methods, I have to return all of the Payment
records where amount_unapplied > 0. If I specify it as one of
the :conditions in a find, such as:
pmts = Payment.find(:all, :conditions => amount_unapplied > 0)
I get an “undefined local variable or method `amount_unapplied’”
exception, as there is no actual column called amount_unapplied…
Any ideas? Thanks!
You could create a custom method in your model…
def self.unapplied_payments
find(:all).map {|p| [p] if p.amount_unapplied > 0}.delete_if {|x|
x.nil?}
end
This line finds all payments, uses array.map to step through and keep
the ones that meet the condition amount_unapplied > 0, and deletes out
the leftover nil values (the ones where amount_unapplied <= 0).
Payment.unapplied_payments now returns a collection of payments where
amount_unapplied > 0
This is a starting point. As you can see it makes a full-table select
first and then steps through them - not very efficient. You’d definitely
want to enhance your custom method to take normal :find options and
apply them before the mapping to improve performance.
Option 2 would be to have an “amount_applied” field on your payment
table which you keep up-to-date, then do a normal find with :conditions
on that field. It’s a tradeoff, but here you get to use the power of the
database for the filtering.
Cayce,
That was a beautiful explanation…I think you have much ‘teacher’ in
you.
Where did you find out about the ‘delete_if’ method? I’ve never seen
it before.
Kathleen
[email protected]
On Jun 4, 10:22 pm, Cayce B. [email protected]
[email protected] wrote:
Cayce,
That was a beautiful explanation…I think you have much ‘teacher’ in
you.
Where did you find out about the ‘delete_if’ method? I’ve never seen
it before.
Kathleen
[email protected]
On Jun 4, 10:22�pm, Cayce B. [email protected]
“delete_if” is a standard method on the Ruby Array class - don’t forget
it’s all Ruby underneath!
RDoc Documentation for documentation of Ruby classes. Click
on “Array” or “String” or “Integer” under Classes and you’ll see
documentation of all the standard methods.
Glad I could help and I appreciate the kind words.