views:

1222

answers:

4

Hi,

I'm slightly insecure about my breadcrumb solution. Names and links are defined in each controller action:

<a href="http://localhost:3000/"&gt;Home&lt;/a&gt;
<% if defined? @l1_link %>
  > <a href="<%= @l1_link%>"><%= @l1_name %></a>
  <% if defined? @l2_link %>
    > <a href="<%= @l2_link%>"><%= @l2_name %></a>
  <% end %>
<% end %>

This way I can use:

@l1_link = user_path()

Question: As I am not that smart - could this kind of system lead to desaster somewhere down the road? Is this (grossly) inefficient?

+3  A: 

This is mostly a matter of opinion, but anyway:

  1. I would not want that much logic in a view. We've probably all done it, but it gets messy quickly.
  2. The code is not safe against future changes that affect the depth of the tree.
  3. Instead of linked variables *_name and *_link, I'd suggest using proper objects anyway, with some link_to functionality.

You might find Episode 162 of Railscasts of interest for a nice solution that gets by with

<% for page in @page.ancestors.reverse %>
  <%= link_to h(page.name), page %> &gt;
<% end %>
Christopher Creutzig
+2  A: 

Here are two approaches:

Split the URL and display it

A more flexible solution implemented in the controller where you setup the breadcrumbs in the controller: Easy and Flexible Breadcrumbs for Rails

Lolindrath
+1  A: 

Breadcrumbs menu are a recurrent pattern in most Rails applications. To solve this issue, I created and released a plugin called breadcrumbs_on_rails.

You define your breadcrumbs in the controller

class MyController

  add_breadcrumb "home", root_path
  add_breadcrumb "my", my_path

  def index
    # ...

    add_breadcrumb "index", index_path
  end

end

and you render them in your view.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  <title>untitled</title>
</head>

<body>
  <%= render_breadcrumbs %>
</body>
</html>

Even if you don't want to use a plugin, I encourage you to give it a look. It's open source and you can grab some idea for your app.

Simone Carletti
This is good, but breadcrumbs seem like a view responsibility instead of a controller responsibility. I'd recommend moving the add_breadcrumb method call to your view.
Ben
You can call the method in your controller as well in your view. The controller allows you to define a per-controller navigation level to reduce code duplication in your views.
Simone Carletti
+1  A: 

Here is a plugin for creating breadcrumbs in Ruby on Rails: Ruby on Rails breadcrumbs plugin. The plugin is from my homepage.

Example configuration:

Gretel::Crumbs.layout do

  crumb :root do
    link "Home", root_path
  end

  crumb :projects do
    link "Projects", projects_path
  end

  crumb :project do |project|
    link project.name, project_path(project)
    parent :projects
  end

  crumb :project_issues do |project|
    link "Issues", project_issues_path(project)
    parent :project, project
  end

  crumb :issue do |issue|
    link issue.name, issue_path(issue)
    parent :project_issues, issue.project
  end

end

In your view:

<% breadcrumb :issue, @issue %>

In your app/views/layouts/application.html.erb:

<%= breadcrumb :pretext => "You are here:", :separator => ">", :autoroot => true, :home_alone => true, :link_last => false %>

Best regards, Lasse

Lasse Bunk