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 received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
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. -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
KathysKode-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
2008-Jun-05 14:05 UTC
Re: Find based on conditions defined in the model
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-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org On Jun 4, 10:22 pm, Cayce Balara <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> 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. > -- > Posted viahttp://www.ruby-forum.com/.- Hide quoted text - > > - Show quoted text ---~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
KathysKode-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org 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 > KathysKode-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org > > On Jun 4, 10:22�pm, Cayce Balara <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org>"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. -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---