неопределенная локальная переменная current_tab — Книга Rails Views, глава 1

В настоящее время я просматриваю книгу Rails Views, Ch 1 - Layouts, и не могу понять, почему я продолжаю получать следующее сообщение об ошибке:

undefined local variable or method `current_tab' for #`
Extracted source (around line #4):
1: <% content_for :main_navigation do %>
2: <nav id="main_nav" role="navigation">
3:  <ul>
4:      <%= nav_tab 'Home', root_path, current: current_tab %></li>
5:      <%= nav_tab 'Creations', creations_path, current: current_tab %></li>
6:      <%= nav_tab 'Campaigns', campaigns_path, current: current_tab %></li>
7:      <%= nav_tab 'Projects', projects_path, current: current_tab %></li>

app/views/layouts/_main_nav.html.erb:4:in `block in _app_views_layouts__main_nav_html_erb__163583644_37720476'
app/views/layouts/_main_nav.html.erb:1:in `_app_views_layouts__main_nav_html_erb__163583644_37720476'
app/helpers/navigation_helper.rb:9:in `currently_at'
app/views/static_pages/home.html.erb:1:in `_app_views_static_pages_home_html_erb___39106558_37242780'

Вот соответствующие файлы в миксе:

Application.html.erb

<body>
    <%= render 'layouts/header' %>

_header.html.erb

<header id="page_header" role="banner">
    <nav id="utility">
        <p>
            You are logged in as <strong>Mat Bloody Cauthon</strong>
            <%= link_to "[Your Account]", "#" %> |
            <%= link_to "[Logout]", "#" %>
        </p>
    </nav>
    <%= link_to(image_tag("logo.png", alt: "Artflow", id: "logo"), root_url, title: "Dashboard") %>

    <%= yield :main_navigation %>
</header>

_main_nav.html.erb

<% content_for :main_navigation do %>
<nav id="main_nav" role="navigation">
    <ul>
        <%= nav_tab 'Home', root_path, current: current_tab %></li>
        <%= nav_tab 'Creations', creations_path, current: current_tab %></li>
        <%= nav_tab 'Campaigns', campaigns_path, current: current_tab %></li>
        <%= nav_tab 'Projects', projects_path, current: current_tab %></li>
        <%= nav_tab 'Designers', designers_path, current: current_tab %></li>
    </ul>
</nav>
<% end %>

navigation_helper.rb

module NavigationHelper
    def nav_tab(title, url, options={})
        current_tab = options.delete(:current)
        options[:class] = (current_tab == title) ? 'active' : 'inactive'
        content_tag(:li, link_to(title, url), options)
    end

    def currently_at(tab)
        render 'layouts/main_nav', locals: {current_tab: tab}
    end
end

home.html.erb (root_path)

<%= currently_at 'Home' %>

Я действительно пытаюсь понять порядок, в котором Ruby загружает вещи, поскольку я думаю, что это может быть частью этого. Вот поток, как я его понимаю:

  1. Пользователь переходит на корневую страницу (home.html.erb)
  2. Загружается Application.html.erb, частичный рендеринг _header.html.erb
  3. _header.html.erb дает _main_nav.html.erb через :main_navigation
  4. _main_nav вызывает nav_tab() из navigation_helper.rb для настройки ссылок
  5. Вернуться к Application.html.erb, который дает home.html.erb
  6. Home вызывает в настоящее время_at() из navigation_helper.rb, который отображает партиал _main_nav.html.erb, который должен отображать навигацию на текущей странице.

Является ли эта прогрессия правильной? Если да, то почему рельсы задыхаются от currently_at, который, похоже, устанавливает current_tab?


person JStandard    schedule 02.07.2013    source источник
comment
@DaveNewton current_tab является локальным для партиала main_nav, который передается помощнику и извлекается из него.   -  person Chris Heald    schedule 03.07.2013
comment
@ChrisHeald О, вот и пропустил.   -  person Dave Newton    schedule 03.07.2013
comment
Нашел проблему. Оказывается, проблема заключалась в хитрости использования render в качестве сокращения для render partial: в моей функции currently_at. Простое использование render явно игнорирует передаваемые локальные переменные, поэтому мне нужно было использовать полный синтаксис render partial:   -  person JStandard    schedule 03.07.2013
comment
Слишком плохо, чтобы ответить на мой собственный вопрос, опубликую это здесь позже:   -  person JStandard    schedule 03.07.2013


Ответы (1)


Оказывается, проблема была в том, что в моем currently_at() строка:

render 'layouts/main_nav', locals: {current_tab: tab}

игнорирует передаваемые локальные переменные, поскольку использует сокращенную версию render partial:

Изменение этой строки на:

render partial: 'layouts/main_nav', locals: {current_tab: tab}

устраняет проблему.

Этот вопрос помог мне прийти в себя: Render @object and locals vs render :partial

Я благодарен тем, кто посмотрел, теперь мы все можем пойти пить пиво за наши проблемы. (по крайней мере, это мой план)

person JStandard    schedule 03.07.2013