# Breadcrumbs?

**URL:** <https://www.ruby-forum.com/t/breadcrumbs/83239>\
**Category:** Rails\
**Created:** [March 17, 2006, 5:46pm UTC](https://www.ruby-forum.com/t/breadcrumbs/83239 "2006-03-17T17:46:39Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![christ](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/8e8cbc/32.png) [@christ](https://www.ruby-forum.com/u/christ)\
**Post date:** [March 17, 2006, 5:46pm UTC](https://www.ruby-forum.com/t/breadcrumbs/83239/1 "2006-03-17T17:46:39Z")

</div>

Before I start down this road, has anyone done a breadcrumbs  
implementation they’d be happy to share?

Thanks  
Chris T

---

<div class="post-metadata">

**Author:** ![christ](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/8e8cbc/32.png) [@christ](https://www.ruby-forum.com/u/christ)\
**Post date:** [March 17, 2006, 5:49pm UTC](https://www.ruby-forum.com/t/breadcrumbs/83239/2 "2006-03-17T17:49:45Z")

</div>

I’ve only done them by hand. I can’t seem to wrap my head around an  
automated process.

---

<div class="post-metadata">

**Author:** ![christ](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/8e8cbc/32.png) [@christ](https://www.ruby-forum.com/u/christ)\
**Post date:** [March 17, 2006, 6:33pm UTC](https://www.ruby-forum.com/t/breadcrumbs/83239/3 "2006-03-17T18:33:24Z")

</div>

On 3/17/06, ChrisT [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Before I start down this road, has anyone done a breadcrumbs  
> implementation they’d be happy to share?

The way I have my site set up, each page is an instance of a model  
that acts\_as\_tree, has a “full\_path” attribute, and a “title”  
attribute (using a mixin). This lets me use a simple helper to build  
the breadcrumbs. It looks something like this:

def breadcrumbs(page, separator = “»”)  
pages = [page.title] # current page  
while page.has\_parent?  
page = page.parent  
pages \<\< link\_to(page.title, “/#{page.full\_path}”)  
end  
pages.reverse.join(" #{separator} ")  
end

Not sure if that helps for your setup but figured I’d share anyway…

If anyone’s done something more generic I’d also like to see it.

Thanks,  
Justin

---

<div class="post-metadata">

**Author:** ![christ](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/8e8cbc/32.png) [@christ](https://www.ruby-forum.com/u/christ)\
**Post date:** [March 17, 2006, 7:45pm UTC](https://www.ruby-forum.com/t/breadcrumbs/83239/4 "2006-03-17T19:45:01Z")

</div>

> each page is an instance of a model

What does this mean? The html that is output _is_ and instance of a  
model? You have a db table that has a record for each view?

Thanks,  
Peter

---

<div class="post-metadata">

**Author:** ![christ](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/8e8cbc/32.png) [@christ](https://www.ruby-forum.com/u/christ)\
**Post date:** [March 17, 2006, 8:13pm UTC](https://www.ruby-forum.com/t/breadcrumbs/83239/5 "2006-03-17T20:13:21Z")

</div>

On 3/17/06, Peter M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > each page is an instance of a model
> 
> What does this mean? The html that is output _is_ and instance of a  
> model? You have a db table that has a record for each view?

Each page represents a row in a db table. So if I visit /foo/bar, I  
find the row with a path of “foo” who’s parent is a row with path  
“bar”

Make sense?

Justin

---

<div class="post-metadata">

**Author:** ![christ](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/8e8cbc/32.png) [@christ](https://www.ruby-forum.com/u/christ)\
**Post date:** [March 17, 2006, 7:25pm UTC](https://www.ruby-forum.com/t/breadcrumbs/83239/6 "2006-03-17T19:25:50Z")

</div>

Thanks  
Looks good. My model is a (self-ref) HABTM so will need a bit of  
tweaking, but that’s a good start.  
Cheers  
Chris T

---

<div class="post-metadata">

**Author:** ![christ](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/8e8cbc/32.png) [@christ](https://www.ruby-forum.com/u/christ)\
**Post date:** [June 28, 2006, 6:18pm UTC](https://www.ruby-forum.com/t/breadcrumbs/83239/7 "2006-06-28T18:18:38Z")

</div>

Justin B. wrote:

> On 3/17/06, ChrisT [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> 
> > Before I start down this road, has anyone done a breadcrumbs  
> > implementation they’d be happy to share?
> 
> The way I have my site set up, each page is an instance of a model  
> that acts\_as\_tree, has a “full\_path” attribute, and a “title”  
> attribute (using a mixin). This lets me use a simple helper to build  
> the breadcrumbs. It looks something like this:
> 
> def breadcrumbs(page, separator = “»”)  
> pages = [page.title] # current page  
> while page.has\_parent?  
> page = page.parent  
> pages \<\< link\_to(page.title, “/#{page.full\_path}”)  
> end  
> pages.reverse.join(" #{separator} ")  
> end
> 
> Not sure if that helps for your setup but figured I’d share anyway…
> 
> If anyone’s done something more generic I’d also like to see it.
> 
> Thanks,  
> Justin

Justin,

Do you generate your page model instances statically when you start the  
app. or do you build the tree dynamically as you navigate?

Wes

---

<div class="post-metadata">

**Author:** ![christ](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/8e8cbc/32.png) [@christ](https://www.ruby-forum.com/u/christ)\
**Post date:** [June 28, 2006, 6:39pm UTC](https://www.ruby-forum.com/t/breadcrumbs/83239/8 "2006-06-28T18:39:46Z")

</div>

ChrisT,  
I’ve been hard coding breadcrumbs based on the current controller/action  
to some success. This works fine when there’s only one trail through a  
set of pages, but when different trails converge it can get complicated.

For example, suppose itâ??s possible to arrive at the Edit action through  
two paths:  
Search -\> View -\> Edit  
Creation -\> View -\> Edit

Since the breadcrumbs are hard coded, itâ??s difficult to figure out what  
to show the user while in Edit, without keeping track of their history  
somehow, which gets messy.

I ended up using alias\_method() to sort of clone some actions, so I  
could give each version itâ??s own breadcrumbs. In this case, I used  
something like this:

alias\_method :original\_edit, :edit  
def search\_edit  
original\_edit  
end

Now when the user is in the Search leg of their trip, all references to  
Edit are actually pointing to Search\_edit, which is identical in every  
way except the name. And old Edit works, too. Just make sure you put  
Edit above the alias\_method() call, or else things can go haywire. This  
way I can show the appropriate search breadcrumbs while in Search\_edit.

I do keep track of form data in sessions (session [:whatever] =  
params[:whatever]), which then can be unpacked into fields when the user  
clicks back in the breadcrumb trail to a previous page with a form.

I donâ??t know if this is the best way to do breadcrumbs, but it works  
without too much extra code. Whipping alias\_method() around like this  
might not be best practice either, I donâ??t know. Anyone have any  
thoughts on it?

ChrisT wrote:

> Before I start down this road, has anyone done a breadcrumbs  
> implementation they’d be happy to share?
> 
> Thanks  
> Chris T

---

<div class="post-metadata">

**Author:** ![christ](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/8e8cbc/32.png) [@christ](https://www.ruby-forum.com/u/christ)\
**Post date:** [June 28, 2006, 8:04pm UTC](https://www.ruby-forum.com/t/breadcrumbs/83239/9 "2006-06-28T20:04:54Z")

</div>

Curtis S. wrote:

> On 6/28/06, Doug [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> 
> > I’ve been hard coding breadcrumbs based on the current controller/action  
> > to some success. This works fine when there’s only one trail through a  
> > set of pages, but when different trails converge it can get complicated.
> 
> I actually had to do this globally for an app in Java. If I had to  
> design it for RoR, I think I would do a similar thing. Basically I  
> created a table and structure for the breadcrumbs. There are a few  
> classes (models) to manage it. It could be implemented via  
> before\_filters and probably could even be refactored into a plugin.  
> Regardless, a basic breakdown:
> 
> id  
> user\_id  
> page\_name  
> sort\_order  
> url
> 
> There was a class that managed that so you could create an entry  
> simply, and also get back a sorted collection of the user’s breadcrumb  
> position. It kinda worked like a “stack” (push / pop). Although a  
> “pop” would clear everything with a sort order equal or higher to the  
> clicked link.
> 
> In RoR, I would probably replace the url field with separate fields  
> for controller, action, and maybe params or something. Depends on  
> your needs to be able to backtrack. And again I would utilize  
> controller before\_filter and after\_filter definitions to manage the  
> breadcrumb trail.
> 
> -Curtis

Curtis,

Did you have to persist this data it to a DB? Were you wanting to allow  
breadcrumbs to work across sessions? _scratching head_

Wes

---

<div class="post-metadata">

**Author:** ![christ](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/8e8cbc/32.png) [@christ](https://www.ruby-forum.com/u/christ)\
**Post date:** [June 28, 2006, 8:01pm UTC](https://www.ruby-forum.com/t/breadcrumbs/83239/10 "2006-06-28T20:01:31Z")

</div>

On 6/28/06, Doug [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> I’ve been hard coding breadcrumbs based on the current controller/action  
> to some success. This works fine when there’s only one trail through a  
> set of pages, but when different trails converge it can get complicated.

I actually had to do this globally for an app in Java. If I had to  
design it for RoR, I think I would do a similar thing. Basically I  
created a table and structure for the breadcrumbs. There are a few  
classes (models) to manage it. It could be implemented via  
before\_filters and probably could even be refactored into a plugin.  
Regardless, a basic breakdown:

id  
user\_id  
page\_name  
sort\_order  
url

There was a class that managed that so you could create an entry  
simply, and also get back a sorted collection of the user’s breadcrumb  
position. It kinda worked like a “stack” (push / pop). Although a  
“pop” would clear everything with a sort order equal or higher to the  
clicked link.

In RoR, I would probably replace the url field with separate fields  
for controller, action, and maybe params or something. Depends on  
your needs to be able to backtrack. And again I would utilize  
controller before\_filter and after\_filter definitions to manage the  
breadcrumb trail.

-Curtis

---

<div class="post-metadata">

**Author:** ![christ](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/8e8cbc/32.png) [@christ](https://www.ruby-forum.com/u/christ)\
**Post date:** [June 28, 2006, 8:49pm UTC](https://www.ruby-forum.com/t/breadcrumbs/83239/11 "2006-06-28T20:49:03Z")

</div>

On 6/28/06, Wes G. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Did you have to persist this data it to a DB? Were you wanting to allow  
> breadcrumbs to work across sessions? _scratching head_

Well, see I’m strange. In every case that I’ve developed a  
“session-only” mechanism, something went wrong (either I had to  
persist it, or someone did something to make it too large to be  
practical at a session level). So I’ve gotten to the point that  
almost _everything_ goes into the DB. If you delete it when it’s not  
neccessary, it doesn’t cause an issue. And if you index properly,  
it’s plenty quick.

Short answer no. Long answer, it was easier and cleaner this way…  
I don’t mind a few milliseconds on a page load (sessions are coming  
from somewhere too…). I also like to “see” what is happening with  
my data, and semi-persistent storage is the best way I’ve found to do  
that on a consistent, debuggable basis.

You could just as easily create it as a hash of objects that don’t  
interact with a DB and just store it in the session. I don’t like  
storing objects in sessions for many reasons. The biggest is  
“updating” a class and having serialization break on you when you  
upload the new version and all currently-sessioned users throwing  
exceptions like the plague… Not a good start to a weekend. 😉

-Curtis
