# ActiveRecord::Base#find(\*a) - but no &b !?

**URL:** <https://www.ruby-forum.com/t/activerecord-base-find-a-but-no-b/49453>\
**Category:** Rails\
**Created:** [December 4, 2005, 8:32pm UTC](https://www.ruby-forum.com/t/activerecord-base-find-a-but-no-b/49453 "2005-12-04T20:32:04Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![ara.t.howard](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a8b319/32.png) [@ara.t.howard](https://www.ruby-forum.com/u/ara.t.howard)\
**Post date:** [December 4, 2005, 8:32pm UTC](https://www.ruby-forum.com/t/activerecord-base-find-a-but-no-b/49453/1 "2005-12-04T20:32:04Z")

</div>

what’s the rational behind not letting the find method receive a block  
as in

@students = []

Student.find(:all) do |student|  
@students \<\< student if student.age \< rand(42)  
end

are there development plans for the omitted block to these functions?  
to me  
it seems natural to use it for a cursor/iterator function that would  
allow  
very complex post filtering of results and, most notably, early break in  
cases  
where a big query must be returned but not results would actually be  
used.

sorry if this has come up before.

kind regards.

## -a

# =============================================================================== | ara [dot] t [dot] howard [at] noaa [dot] gov | all happiness comes from the desire for others to be happy. all misery | comes from the desire for oneself to be happy. | – bodhicaryavatara

---

<div class="post-metadata">

**Author:** ![ara.t.howard](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a8b319/32.png) [@ara.t.howard](https://www.ruby-forum.com/u/ara.t.howard)\
**Post date:** [December 4, 2005, 8:56pm UTC](https://www.ruby-forum.com/t/activerecord-base-find-a-but-no-b/49453/2 "2005-12-04T20:56:29Z")

</div>

You can do  
Student.find(:all).each do |student|

Also instead of pulling all the student records and then generating  
that list, you could do an SQL query instead. Unfortunately I don’t  
know the exact syntax off the top of my head, but I know it’s been  
covered a lot on the list.

Pat

---

<div class="post-metadata">

**Author:** ![ara.t.howard](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a8b319/32.png) [@ara.t.howard](https://www.ruby-forum.com/u/ara.t.howard)\
**Post date:** [December 4, 2005, 8:56pm UTC](https://www.ruby-forum.com/t/activerecord-base-find-a-but-no-b/49453/3 "2005-12-04T20:56:30Z")

</div>

Also, I’m sure that the rationale is probably similar to why you can’t  
do  
@students = []  
@students do |student|

🙂

---

<div class="post-metadata">

**Author:** ![ara.t.howard](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a8b319/32.png) [@ara.t.howard](https://www.ruby-forum.com/u/ara.t.howard)\
**Post date:** [December 5, 2005, 4:51am UTC](https://www.ruby-forum.com/t/activerecord-base-find-a-but-no-b/49453/4 "2005-12-05T04:51:51Z")

</div>

On Dec 4, 2005, at 11:30 AM, Ara.T.Howard wrote:

> are there development plans for the omitted block to these  
> kind regards.
> 
> ## -a

I like this idea Ara. I would use this as a patch if you made one. I  
don’t know if there is some reason to not allow this though.

Cheers-  
-Ezra Z.  
WebMaster  
Yakima Herald-Republic Newspaper  
removed\_email\_address@domain.invalid  
509-577-7732

---

<div class="post-metadata">

**Author:** ![ara.t.howard](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a8b319/32.png) [@ara.t.howard](https://www.ruby-forum.com/u/ara.t.howard)\
**Post date:** [December 5, 2005, 6:14pm UTC](https://www.ruby-forum.com/t/activerecord-base-find-a-but-no-b/49453/5 "2005-12-05T18:14:46Z")

</div>

> ```
> if can_contact(responder.contact_info)
> 
> ```
> 
> reduce memory usage in many cases.  
> I think you’re missing the point on how SQL databases work. Are you  
> suggesting that we make n queries to pull n items out of the table?  
> Regardless of memory usage, this is probably a bad idea, since SQL  
> communications are expensive compared to, say, garbage collection. A  
> good solution within the current framework would be to use the limit  
> and offset specifiers to grab, say 100 entries at a time and iterate  
> over them the “old” way. There’s no meaningful way to abort an  
> in-progress query over SQL, nor, as I understand the DBI,  
> incrementally unpack a query (though a lazy database interface would  
> be pretty neat, I don’t know that it is well defined with regard to  
> ALL supported database backends).

Brian

---

<div class="post-metadata">

**Author:** ![ara.t.howard](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a8b319/32.png) [@ara.t.howard](https://www.ruby-forum.com/u/ara.t.howard)\
**Post date:** [December 4, 2005, 9:16pm UTC](https://www.ruby-forum.com/t/activerecord-base-find-a-but-no-b/49453/6 "2005-12-04T21:16:56Z")

</div>

On Sun, 4 Dec 2005, Pat M. wrote:

> You can do  
> Student.find(:all).each do |student|
> 
> Also instead of pulling all the student records and then generating that  
> list, you could do an SQL query instead. Unfortunately I don’t know the  
> exact syntax off the top of my head, but I know it’s been covered a lot on  
> the list.
> 
> Pat

this is very different. for example

Student.find(:all).each do |student|  
end

this says

find all 1,000,000,000,000 students as an array. then run  
each(&block) over  
that entire result set. it’s **exactly** equiv to this:

students = Student::find :all

students.each do |student|  
end

and saves you nothing at all in terms of speed or space. allowing #find  
to  
take a block solves a different problem than selecting by sql/condition.  
for  
example, say you’re writing a wilderness 911 website that will iterate  
over a  
list of volunteer responders and attempt to contact each one via a text  
message. as soon as a single responder is found and contaceted he will  
be  
recorded as being on the case. so you might say

r = nil

Responder::find(:all) do |responder|  
if can\_contact(responder.contact\_info)  
r = responder and break  
end  
end

# do something with r

now imagine the responder table has a million records. in this case you  
only  
keep **one** record in memory at a time and can break as soon as your  
condition is met. you cannot do this kind of logic with sql so a block  
makes  
filtering your results after sql/select possible and has the potential  
to  
reduce memory usage in many cases.

regards.

## -a

# =============================================================================== | ara [dot] t [dot] howard [at] noaa [dot] gov | all happiness comes from the desire for others to be happy. all misery | comes from the desire for oneself to be happy. | – bodhicaryavatara

---

<div class="post-metadata">

**Author:** ![ara.t.howard](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a8b319/32.png) [@ara.t.howard](https://www.ruby-forum.com/u/ara.t.howard)\
**Post date:** [December 5, 2005, 6:35pm UTC](https://www.ruby-forum.com/t/activerecord-base-find-a-but-no-b/49453/7 "2005-12-05T18:35:12Z")

</div>

On Mon, 5 Dec 2005, Brian L. wrote:

> I think you’re missing the point on how SQL databases work. Are you  
> suggesting that we make n queries to pull n items out of the table?

no. in fact most ruby database apis work to support this already. for  
example:

harp:~ \> cat a.rb  
require “sqlite”

db = SQLite::Database::new “db”, 0

p db.execute(“select \* from foo”).size

db.execute(“select \* from foo”) do |tuple|  
p tuple  
break  
end

harp:~ \> ruby a.rb  
3  
{0=\>“1”, “x”=\>“1”}

this is one query and saves **massively** on memory for large queries.  
try  
something like the above in sqlite or postgres with a result set of  
1,000,000  
rows and check the memory usage on your machine. by using an iterator  
(block)  
you will see zero memory usage. if you merely say

result = db.execute sql

memory will vanish.

> Regardless of memory usage, this is probably a bad idea, since SQL  
> communications are expensive compared to, say, garbage collection. A good  
> solution within the current framework would be to use the limit and offset  
> specifiers to grab, say 100 entries at a time and iterate over them the  
> “old” way.

this is very dangerous unless done within a transaction since the  
queries will  
not be isolated.

> There’s no meaningful way to abort an in-progress query over SQL,  
> nor, as I understand the DBI, incrementally unpack a query (though a lazy  
> database interface would be pretty neat, I don’t know that it is well  
> defined with regard to ALL supported database backends).

see example above. for databases which don’t support it can easily be  
made to  
support the same interface:

```
 def execute sql
   if block_given?
     conn.execute(sql).each{|tuple| yield tuple}
   else
     conn.execute(sql)
   end
 end

```

regards.

## -a

# =============================================================================== | ara [dot] t [dot] howard [at] noaa [dot] gov | all happiness comes from the desire for others to be happy. all misery | comes from the desire for oneself to be happy. | – bodhicaryavatara
