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:
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:
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
KathysKode@gmail.com
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
KathysKode@gmail.com
On Jun 4, 10:22�pm, Cayce Balara <rails-mailing-l...@andreas-s.net>
"delete_if" is a standard method on the Ruby Array class - don't forget
it's all Ruby underneath!
http://www.ruby-doc.org/core/ 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.