Ankur Jain
2012-Apr-19 21:03 UTC
Trivial Rails Question, I am unable to explain the behavior
Following 2 statements look identical to me, however the first one returns only one object but the second one returns correctly an array of 4 objects. What is happening here is simple, I get all the Grade objects (1st one using Grade.find(:all) and second one using Grade.all), and then filter out all the grade objects where they have worksheets assigned to them. * * *@grades = Grade.find(:all){|grade| Worksheet.find(:all,:conditions=> [''grade_id =?'',grade.id]).count > 0}* * * *@grades = Grade.all {|grade| Worksheet.find(:all,:conditions=> [''grade_id =?'',grade.id]).count > 0}* Can somebody explain why the results would be different for these 2 statements. -- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Tyler
2012-Apr-20 02:08 UTC
Re: Trivial Rails Question, I am unable to explain the behavior
I don''t have rails in front of me, but looks like there may be a problem with implied parentheses. Have you tried things like: *@grades = Grade.all() {|grade| Worksheet.find(:all,:conditions=> [''grade_id =?'',grade.id]).count > 0}* * * Again I can''t test so not sure if that helps On Thursday, April 19, 2012 2:03:05 PM UTC-7, Ankur Jain wrote:> > Following 2 statements look identical to me, however the first one returns > only one object but the second one returns correctly an array of 4 objects. > > What is happening here is simple, I get all the Grade objects (1st one > using Grade.find(:all) and second one using Grade.all), and then filter out > all the grade objects where they have worksheets assigned to them. > > > * > * > *@grades = Grade.find(:all){|grade| Worksheet.find(:all,:conditions=> > [''grade_id =?'',grade.id]).count > 0}* > * > * > *@grades = Grade.all {|grade| Worksheet.find(:all,:conditions=> > [''grade_id =?'',grade.id]).count > 0}* > > Can somebody explain why the results would be different for these 2 > statements. > >-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To view this discussion on the web visit https://groups.google.com/d/msg/rubyonrails-talk/-/iP-o3etIsskJ. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Dheeraj Kumar
2012-Apr-20 02:14 UTC
Re: Trivial Rails Question, I am unable to explain the behavior
The find method takes the option hash as the last parameter. Either use Model.all(options) or Model.find(:all, options) The correct code is: @grades = Grade.find(:all, {|grade| Worksheet.find(:all,:conditions=> [''grade_id =?'',grade.id (http://grade.id)]).count > 0}) Dheeraj Kumar On Friday 20 April 2012 at 7:38 AM, Tyler wrote:> I don''t have rails in front of me, but looks like there may be a problem with implied parentheses. Have you tried things like: > @grades = Grade.all() {|grade| Worksheet.find(:all,:conditions=> [''grade_id =?'',grade.id (http://grade.id/)]).count > 0} > > Again I can''t test so not sure if that helps > > > On Thursday, April 19, 2012 2:03:05 PM UTC-7, Ankur Jain wrote: > > Following 2 statements look identical to me, however the first one returns only one object but the second one returns correctly an array of 4 objects. > > > > What is happening here is simple, I get all the Grade objects (1st one using Grade.find(:all) and second one using Grade.all), and then filter out all the grade objects where they have worksheets assigned to them. > > > > > > > > @grades = Grade.find(:all){|grade| Worksheet.find(:all,:conditions=> [''grade_id =?'',grade.id (http://grade.id)]).count > 0} > > > > @grades = Grade.all {|grade| Worksheet.find(:all,:conditions=> [''grade_id =?'',grade.id (http://grade.id)]).count > 0} > > > > Can somebody explain why the results would be different for these 2 statements. > > > -- > You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. > To view this discussion on the web visit https://groups.google.com/d/msg/rubyonrails-talk/-/iP-o3etIsskJ. > To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org (mailto:rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org). > To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org (mailto:rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org). > For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.-- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Matt Jones
2012-Apr-20 14:22 UTC
Re: Trivial Rails Question, I am unable to explain the behavior
On Thursday, 19 April 2012 22:14:51 UTC-4, Dheeraj Kumar wrote:> > The find method takes the option hash as the last parameter. Either use > Model.all(options) or Model.find(:all, options) > > The correct code is: > * > * > *@grades = Grade.find(:all, {|grade| Worksheet.find(:all,:conditions=> > [''grade_id =?'',*grade.id*]).count > 0})* > * > * > * > * >Um, no. That won''t even parse.> On Friday 20 April 2012 at 7:38 AM, Tyler wrote: > > I don''t have rails in front of me, but looks like there may be a problem > with implied parentheses. Have you tried things like: > *@grades = Grade.all() {|grade| Worksheet.find(:all,:conditions=> > [''grade_id =?'',grade.id]).count > 0}* * > * > > Again I can''t test so not sure if that helps > > > On Thursday, April 19, 2012 2:03:05 PM UTC-7, Ankur Jain wrote: > > Following 2 statements look identical to me, however the first one returns > only one object but the second one returns correctly an array of 4 objects. > > What is happening here is simple, I get all the Grade objects (1st one > using Grade.find(:all) and second one using Grade.all), and then filter out > all the grade objects where they have worksheets assigned to them. > > > * > * > *@grades = Grade.find(:all){|grade| Worksheet.find(:all,:conditions=> > [''grade_id =?'',grade.id]).count > 0}* > * > * > *@grades = Grade.all {|grade| Worksheet.find(:all,:conditions=> > [''grade_id =?'',grade.id]).count > 0}* > >There are two things going on here: - in the first statement, find(:all) acts like Enumerable#find when passed a block. Each of the found objects is passed to the block and the first one that returns a truthy value is returned. - in the second statement, all doesn''t call the block so you get exactly the same results you would have without a block at all. If this is an operation you do a lot in your app, you may want to check out the :counter_cache option of belongs_to, which will allow you to write this (correctly) as: @grades = Grade.where(''worksheets_count > 0'').all Also note that if counts are all you''re looking for, you should avoid doing a find(:all) on them (as on Worksheet above); the count method on the model class can do this much more efficiently (with a SQL COUNT statement, rather than loading a bunch of objects and then counting them). --Matt Jones -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To view this discussion on the web visit https://groups.google.com/d/msg/rubyonrails-talk/-/gr_Z8phcivsJ. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Ankur Jain
2012-Apr-20 14:54 UTC
Re: Re: Trivial Rails Question, I am unable to explain the behavior
Thanks Matt, Your alternative method on how to best get the data definitely is a much optimized solution then what I was using, I am not using that and everything works great. However, I am still confused on one part. as per my understanding *Grade.find(:all)* and *Grade.all * both should return an array of Grade objects, so how are the results different if I just pass the objects through this block. {|grade| Worksheet.find(:all,:conditions=> [''grade_id =?'',grade.id]).count> 0}Thanks again for the help. On Fri, Apr 20, 2012 at 10:22 AM, Matt Jones <al2o3cr-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> > > On Thursday, 19 April 2012 22:14:51 UTC-4, Dheeraj Kumar wrote: >> >> The find method takes the option hash as the last parameter. Either use >> Model.all(options) or Model.find(:all, options) >> >> The correct code is: >> * >> * >> *@grades = Grade.find(:all, {|grade| Worksheet.find(:all,:conditions=> >> [''grade_id =?'',*grade.id*]).count > 0})* >> * >> * >> * >> * >> > > Um, no. That won''t even parse. > > > >> On Friday 20 April 2012 at 7:38 AM, Tyler wrote: >> >> I don''t have rails in front of me, but looks like there may be a problem >> with implied parentheses. Have you tried things like: >> *@grades = Grade.all() {|grade| Worksheet.find(:all,:conditions=> >> [''grade_id =?'',grade.id]).count > 0}* * >> * >> >> Again I can''t test so not sure if that helps >> >> >> On Thursday, April 19, 2012 2:03:05 PM UTC-7, Ankur Jain wrote: >> >> Following 2 statements look identical to me, however the first one >> returns only one object but the second one returns correctly an array of 4 >> objects. >> >> What is happening here is simple, I get all the Grade objects (1st one >> using Grade.find(:all) and second one using Grade.all), and then filter out >> all the grade objects where they have worksheets assigned to them. >> >> >> * >> * >> *@grades = Grade.find(:all){|grade| Worksheet.find(:all,:conditions=> >> [''grade_id =?'',grade.id]).count > 0}* >> * >> * >> *@grades = Grade.all {|grade| Worksheet.find(:all,:conditions=> >> [''grade_id =?'',grade.id]).count > 0}* >> >> > There are two things going on here: > > - in the first statement, find(:all) acts like Enumerable#find when passed > a block. Each of the found objects is passed to the block and the first one > that returns a truthy value is returned. > > - in the second statement, all doesn''t call the block so you get exactly > the same results you would have without a block at all. > > If this is an operation you do a lot in your app, you may want to check > out the :counter_cache option of belongs_to, which will allow you to write > this (correctly) as: > > @grades = Grade.where(''worksheets_count > 0'').all > > Also note that if counts are all you''re looking for, you should avoid > doing a find(:all) on them (as on Worksheet above); the count method on the > model class can do this much more efficiently (with a SQL COUNT statement, > rather than loading a bunch of objects and then counting them). > > --Matt Jones > > -- > You received this message because you are subscribed to the Google Groups > "Ruby on Rails: Talk" group. > To view this discussion on the web visit > https://groups.google.com/d/msg/rubyonrails-talk/-/gr_Z8phcivsJ. > > To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org > To unsubscribe from this group, send email to > rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org > For more options, visit this group at > http://groups.google.com/group/rubyonrails-talk?hl=en. >-- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Matt Jones
2012-Apr-21 14:30 UTC
Re: Re: Trivial Rails Question, I am unable to explain the behavior
On Friday, 20 April 2012 10:54:13 UTC-4, Ankur Jain wrote:> > > Thanks Matt, Your alternative method on how to best get the > data definitely is a much optimized solution then what I was using, I am > not using that and everything works great. > > However, I am still confused on one part. > > as per my understanding > > *Grade.find(:all)* > > and > > *Grade.all * > > both should return an array of Grade objects, so how are the results > different if I just pass the objects through this block. > {|grade| Worksheet.find(:all,:conditions=> [''grade_id =?'',grade.id]).count > > 0} > >A block by itself doesn''t do ANYTHING - it''s entirely dependent on the function it''s passed to. For instance: def hello(who) puts "Hello #{who}" end hello(''World'') # prints "Hello World" hello(''World'') { |x| puts ''WAT'' } # prints "Hello World" - doesn''t do anything with the block The case you encountered with find(:all) was specifically coded to use the block just like Enumerable#find: a = [1,2,3,4] a.find { |x| x > 2 } # => returns 3, the first value in the array that the block returns a truthy value for --Matt Jones -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To view this discussion on the web visit https://groups.google.com/d/msg/rubyonrails-talk/-/G8GkmpAI2jwJ. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.