# Performance of find\_page\_by\_url

**URL:** <https://www.ruby-forum.com/t/performance-of-find-page-by-url/81028>\
**Category:** Radiant CMS\
**Created:** [January 3, 2007, 6:13am UTC](https://www.ruby-forum.com/t/performance-of-find-page-by-url/81028 "2007-01-03T06:13:14Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![dasch](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/b2d939/32.png) [@dasch](https://www.ruby-forum.com/u/dasch)\
**Post date:** [January 3, 2007, 6:13am UTC](https://www.ruby-forum.com/t/performance-of-find-page-by-url/81028/1 "2007-01-03T06:13:14Z")

</div>

The performance of find\_by\_url degrades because children don’t  
automatically get a reference to their parent, but they need to get that  
parent reference to compute their url. With a structure of:

- home
  - articles
    - (600 articles here)

To find the nth article will take 2xn db calls - up to 1200 calls in  
this case - each article will make a separate call to retrieve it’s  
parent, then its parent’s parent. Not to mention the fact that all 600  
of those articles are going to be read out by the call to ‘children’  
anyway.

This is the current code (in mental) for find\_by\_url:

def find\_by\_url(url, live = true, clean = true)  
url = clean\_url(url) if clean  
if (self.url == url) && (not live or published?)  
self  
else  
children.each do |child|  
if (url =~ Regexp.compile( ‘^’ + Regexp.quote(child.url))) and  
(not child.virtual?)  
found = child.find\_by\_url(url, live, clean)  
return found if found  
end  
end  
children.find(:first, :conditions =\> “class\_name =  
‘FileNotFoundPage’”)  
end  
end

This could be worked around by putting in:  
children.each do |child|  
child.parent = self  
… etc …

That is a bit hacky though, and will restrict children from overriding  
parent=()

Is there too much useless flexibility here? Do we need to be able to  
have child pages that match urls not defined by their parent and slug  
(things like archive\_page are still just parent+slug)? Why can’t we use  
something like:

def find\_by\_slug\_path(slugs)  
if child = children.find\_by\_slug(slugs[0])  
if slugs.size == 0  
return child  
else  
return child.find\_by\_slug\_path(slugs[1…-1])  
end  
end  
end

and the root Page.find\_by\_url:

def self.find\_by\_url(url)  
root = find\_by\_parent\_id(nil)  
slugs = url.split(’/’).select {|x| x.size \> 0}  
root.find\_by\_slug\_path(slugs)  
end

That would only need to make a single call at each level - each call  
returning a single page.

---

<div class="post-metadata">

**Author:** ![dasch](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/b2d939/32.png) [@dasch](https://www.ruby-forum.com/u/dasch)\
**Post date:** [January 3, 2007, 6:17am UTC](https://www.ruby-forum.com/t/performance-of-find-page-by-url/81028/2 "2007-01-03T06:17:14Z")

</div>

I meant to post that to radiant-core… Sorry to the peoples that are  
scared by such things.

---

<div class="post-metadata">

**Author:** ![dasch](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/b2d939/32.png) [@dasch](https://www.ruby-forum.com/u/dasch)\
**Post date:** [January 3, 2007, 1:32pm UTC](https://www.ruby-forum.com/t/performance-of-find-page-by-url/81028/3 "2007-01-03T13:32:11Z")

</div>

Daniel S. wrote:

> parent, then its parent’s parent. Not to mention the fact that all 600  
> of those articles are going to be read out by the call to ‘children’  
> anyway.

Good point.

> something like:
> 
> …

Archive child pages use parent + date + slug, which is why we need the  
functionality.

> That would only need to make a single call at each level - each call  
> returning a single page.

What about just caching the full URL in the pages table? That way we  
could just do a single query to find the correct page. The disadvantage  
to this approach is that whenever you save a page you will need to  
update all of it’s children if the slug or page\_class has changed.

> I meant to post that to radiant-core…

This kind of discussion is best on the core list.

–  
John L.  
[http://wiseheartdesign.com](http://wiseheartdesign.com)
