在从控制器渲染时,current_page方法似乎不起作用

时间:2015-06-22 10:22:41

标签: ruby-on-rails ruby ruby-on-rails-4 model-view-controller

application.html.erb中包含导航栏。因为对于某些页面,例如注册页面,我需要在导航栏中放置其他代码,我已经排除了这些页面以通过application.html.erb显示导航栏,而是将其包含在各自的视图页面中。请参阅下面的代码。

在注册表单中输入无效数据时会出现问题。然后控制器方法呈现new。但是,application.html.erb似乎并未认识到current_page仍为signup_path,因此未应用该异常,因为该页面上未显示导航栏。因此,当它呈现新的时,导航栏会显示两次:按application.html.erb的顺序显示一次,按视图页面本身的顺序显示一次。

为什么在无效表单条目上呈现新内容时,是否看到它仍然在signup_path上?我应该如何调整我的代码,以便在那种情况下它不会显示导航栏两次?是否有一种方法可以在<%= yield special code if any %>application.html.erb中将<% special_code %> <% end special_code %>包含在将此特殊代码传递给application.html.erb的视图页面中?

在application.html.erb中我有:

<% unless current_page?(signup_path) %>
  <nav class="banner">
    <%= render partial: "shared/header" %>
  </nav>
<% end %>

在我的注册页面视图中:

<nav class="banner">
    <%= render partial: "shared/header" %>
    Additional code that needs to be within 'nav' for this page
</nav>

控制器方法:

def create
  @user = User.new(user_params)
  if @stakeholder.save
    flash[:success] = "A confirmation email has been sent to you."
    redirect_to root_url
  else                          
    render 'new'  ###This is where it goes wrong!
  end
end

2 个答案:

答案 0 :(得分:1)

您可以使用content_foryields在布局中创建视图可以覆盖的默认值。

# layouts/application.html.erb:
<% if content_for?(:banner) %>
  <%= yield(:banner) %>
<% else %>
  <div id="banner">
    <h1>This is the default...</h1>
  </div>
<% end %>

/users/signup.html.erb:
<%- content_for :banner, flush: true do -%>
  <!-- move along, nothing to see here -->
<%- end -%>

这里的优点是你最终不会将你的布局变成条件的鸟巢。您可以轻松地从视图中将任何您想要的内容注入到布局中。

缺点是你必须使用带有HTML注释的愚蠢黑客来覆盖块以显示任何内容,因为content_for?修剪了块。 content_for对片段捕获也不好看。

addded

我在unless current_page?(signup_path)无法正常工作之前没有触及此问题,因为render 'new'并没有神奇地将您带到新的操作。实际上,current_path是/users,因为从表单POST到该URL。

它只是告诉rails找到一个名为'new'的模板并渲染它。

更正版本将是:

<% unless controller_name == 'users' && ['new', 'create'].include?( action_name) %>
  <nav class="banner">
   <%= render partial: "shared/header" %>
  </nav>
<% end %>

答案 1 :(得分:-1)

你完全正确。这是出错的地方

render 'new'  ###This is where it goes wrong!

这里发生了什么

  1. 用户请求new操作,该操作呈现new模板
  2. 用户提交表单,从而请求您的控制器中的create操作
  3. create操作中,您在验证失败时呈现new模板而不是create
  4. 所以基本上用户不再在new页面上,而是在create页面上,其中包含从new呈现的视图。

    最简单的解决方案是将标头的期望更改为newcreate操作,因为您重定向成功,因此您将无法使用它。