# DRYer way to see if array exists before I do a find?

**URL:** <https://www.ruby-forum.com/t/dryer-way-to-see-if-array-exists-before-i-do-a-find/140823>\
**Category:** Rails\
**Created:** [June 18, 2008, 11:42pm UTC](https://www.ruby-forum.com/t/dryer-way-to-see-if-array-exists-before-i-do-a-find/140823 "2008-06-18T23:42:13Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [June 18, 2008, 11:42pm UTC](https://www.ruby-forum.com/t/dryer-way-to-see-if-array-exists-before-i-do-a-find/140823/1 "2008-06-18T23:42:13Z")

</div>

Many times I perform logic where I look to gather an array of records,  
but first must check to see if any exists (so I don’t get an error of  
a .nil array).  
Here is an example of some code I wrote to today, is there a ‘sweeter’  
way to achieve the same results? If so, I would use this style of  
coding many times.  
unless project.vendors.nil?  
@vendors = project.vendors.find(:all)  
for vendor in @vendors  
unless vendor.products.nil?  
@products = vendor.products.find(:all)  
for product in @products  
unless product.prodrevs.nil?  
@prodrevs = product.prodrevs.find(:all)  
for prodrev in @prodrevs  
@prodrevmap \<\< prodrev  
end  
end  
end  
end  
end  
Thanks,  
Kathleen

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [June 19, 2008, 12:19am UTC](https://www.ruby-forum.com/t/dryer-way-to-see-if-array-exists-before-i-do-a-find/140823/2 "2008-06-19T00:19:49Z")

</div>

ok, I’ll bite.

If the goal is get all prodrev’s what’s wrong with Prodrev.find(:all)?

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [June 19, 2008, 12:41am UTC](https://www.ruby-forum.com/t/dryer-way-to-see-if-array-exists-before-i-do-a-find/140823/3 "2008-06-19T00:41:12Z")

</div>

project.vendors.find(:all).each do |vendor|  
vendor.products.find(:all).each do |product|  
product.prodrevs.find(:all).each do |prodrev|  
@prodrevmap \<\< prodrev  
end  
end  
end

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [June 19, 2008, 1:29am UTC](https://www.ruby-forum.com/t/dryer-way-to-see-if-array-exists-before-i-do-a-find/140823/4 "2008-06-19T01:29:15Z")

</div>

On Jun 18, 2008, at 6:40 PM, Marlon M. wrote:

> > Many times I perform logic where I look to gather an array of  
> > unless vendor.products.nil?  
> > end  
> > Thanks,  
> > Kathleen

That’s more compact, but why all the .find(:all) methods? You’re  
looking for all the prodrevs under a project. If I assume:

class Project; has\_many :vendors ;end  
class Vendor ; has\_many :products ;belongs\_to :project ;end  
class Product; has\_many :prodrevs ;belongs\_to :vendor ;end  
class Prodrev; belongs\_to :product ;end

You could:

class Prodrev  
def self.map\_for\_project(project\_id)  
find(:all, :conditions =\> [‘projects.id = ?’, project\_id],  
:select =\> ‘prodrevs.\*’, :readonly =\> false,  
:joins =\> [‘JOIN products ON products.id =  
prodrevs.product\_id’,  
‘JOIN vendors ON vendors.id =  
products.vendor\_id’,  
‘JOIN projects ON projects.id =  
vendors.project\_id’].join(’ '))  
end  
end

@prodrevmap = Prodrev.map\_for\_project(project.id)

If you do this often, you’ll (most likely) benefit from letting the  
database do the joining for you and avoiding all the ActiveRecord  
objects that you’d otherwise create just to reach down to the Prodrevs.

-Rob

Rob B. [http://agileconsultingllc.com](http://agileconsultingllc.com)  
removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [June 19, 2008, 2:30am UTC](https://www.ruby-forum.com/t/dryer-way-to-see-if-array-exists-before-i-do-a-find/140823/5 "2008-06-19T02:30:08Z")

</div>

Marlon,  
Your idea looks very sexy but I suspect that it won’t work if any of  
the finds are unsuccessful. I tried the idea (below) and it seems to  
look the best (so far).  
I’m running this routine to calculate the .xml entries for a Google  
Sitemap…so you should know that this is a special occurance that I’m  
running as a RAKE job.  
If anyone else is tasked with having to create a Google Sitemap on a  
complex database, I’d be happy to share what I have so far.

# Begin - First set of records

```
@prodrevmap = []
@vendors = project.vendors.find(:all) unless project.vendors.nil?
for vendor in @vendors
  @products = vendor.products.find(:all) unless

```

vendor.products.nil?  
for product in @products  
@prodrevs = product.prodrevs.find(:all) unless  
product.prodrevs.nil?  
for prodrev in @prodrevs  
@prodrevmap \<\< prodrev  
end  
end  
end

# end - First set of records

Kathleen

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [June 19, 2008, 2:33am UTC](https://www.ruby-forum.com/t/dryer-way-to-see-if-array-exists-before-i-do-a-find/140823/6 "2008-06-19T02:33:03Z")

</div>

On Jun 18, 2008, at 8:29 PM, removed\_email\_address@domain.invalid wrote:

> If anyone else is tasked with having to create a Google Sitemap on a

have you seen [http://github.com/queso/sitemap/tree/master](http://github.com/queso/sitemap/tree/master)?

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [June 19, 2008, 7:15pm UTC](https://www.ruby-forum.com/t/dryer-way-to-see-if-array-exists-before-i-do-a-find/140823/7 "2008-06-19T19:15:40Z")

</div>

Mr. Cheung,  
You are truly the ‘Zen Master’ of Rails. Thank you for your wonderful  
example.  
Kathleen

On Jun 19, 4:24 am, Frederick C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [June 19, 2008, 12:35pm UTC](https://www.ruby-forum.com/t/dryer-way-to-see-if-array-exists-before-i-do-a-find/140823/8 "2008-06-19T12:35:40Z")

</div>

On 19 Jun 2008, at 01:29, removed\_email\_address@domain.invalid wrote:

> Marlon,  
> Your idea looks very sexy but I suspect that it won’t work if any of  
> the finds are unsuccessful. I tried the idea (below) and it seems to  
> look the best (so far).

find :all and associations that are collections always return an  
array, never nil

You might also try something like

Prodrev.find :all, :joins =\> {:product =\> {:vendor  
=\> :project}}, :conditions =\> [‘projects.id = ?’, project.id]

Fred

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [June 20, 2008, 4:03am UTC](https://www.ruby-forum.com/t/dryer-way-to-see-if-array-exists-before-i-do-a-find/140823/9 "2008-06-20T04:03:10Z")

</div>

Frederick C. wrote:

> Prodrev.find :all, :joins =\> {:product =\> {:vendor  
> =\> :project}}, :conditions =\> [‘projects.id = ?’, project.id]
> 
> Fred

Hey Fred,

How’d you know I needed an example of a nested :joins statement?

🙂

Peace,  
Phillip
