# Find based on conditions defined in the model

**URL:** <https://www.ruby-forum.com/t/find-based-on-conditions-defined-in-the-model/139543>\
**Category:** Rails\
**Created:** [June 4, 2008, 9:39pm UTC](https://www.ruby-forum.com/t/find-based-on-conditions-defined-in-the-model/139543 "2008-06-04T21:39:25Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Neal\_L](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/74df32/32.png) [@Neal\_L](https://www.ruby-forum.com/u/Neal_L)\
**Post date:** [June 4, 2008, 9:39pm UTC](https://www.ruby-forum.com/t/find-based-on-conditions-defined-in-the-model/139543/1 "2008-06-04T21:39:25Z")

</div>

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!

---

<div class="post-metadata">

**Author:** ![Neal\_L](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/74df32/32.png) [@Neal\_L](https://www.ruby-forum.com/u/Neal_L)\
**Post date:** [June 5, 2008, 6:22am UTC](https://www.ruby-forum.com/t/find-based-on-conditions-defined-in-the-model/139543/2 "2008-06-05T06:22:07Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Neal\_L](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/74df32/32.png) [@Neal\_L](https://www.ruby-forum.com/u/Neal_L)\
**Post date:** [June 5, 2008, 4:06pm UTC](https://www.ruby-forum.com/t/find-based-on-conditions-defined-in-the-model/139543/3 "2008-06-05T16:06:16Z")

</div>

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  
removed\_email\_address@domain.invalid

On Jun 4, 10:22 pm, Cayce B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![Neal\_L](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/74df32/32.png) [@Neal\_L](https://www.ruby-forum.com/u/Neal_L)\
**Post date:** [June 5, 2008, 4:33pm UTC](https://www.ruby-forum.com/t/find-based-on-conditions-defined-in-the-model/139543/4 "2008-06-05T16:33:05Z")

</div>

removed\_email\_address@domain.invalid 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  
> removed\_email\_address@domain.invalid
> 
> On Jun 4, 10:22ï¿½pm, Cayce B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

“delete\_if” is a standard method on the Ruby Array class - don’t forget  
it’s all Ruby underneath! 🙂

[RDoc Documentation](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.
