0

我有一個導航欄,包含在application.html.erb中。由於對於某些頁面(如註冊頁面),我需要在導航欄中放置其他代碼,因此我已將這些頁面排除在外,以顯示通過application.html.erb的導航欄,並將其包括在各自的視圖頁面中。見下面的代碼。從控制器渲染時,current_page方法似乎不起作用

在註冊表單中輸入無效數據時出現問題。控制器方法然後呈現new。然而,application.html.erb似乎沒有認識到current_page仍然是signup_path,因此不會在該頁面上不顯示導航欄的情況下應用該例外。因此,當它呈現新的時候,導航欄會顯示兩次:按照application.html.erb的順序顯示一次,並按照查看頁面本身的順序顯示一次。

爲什麼在無效表單條目上呈現新的時候,它沒有看到它仍然在signup_path?我應該如何調整我的代碼,使其在這種情況下不會顯示導航欄兩次?是否有在application.html.erb<% special_code %> <% end special_code %>包含<%= yield special code if any %>在通過此特殊代碼application.html.erb查看頁面的方式?


在application.html.erb我:

在我註冊頁面視圖:

<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 

回答

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的。

它只是告訴軌道找到一個名爲'新'的模板,並呈現它。

一個修正版本是:

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

太好了,我想我已經開始工作了!我不確定兩件事情:1)不明白你對HTML評論的含義。沒有必要包括「沿着」行,或者在那裏?在沒有任何要添加到橫幅的頁面上,我沒有包含'content_for'代碼,而在確實需要添加代碼的頁面上添加的代碼不是「沿着」行。它是否正確? 2)搜索理解片段捕捉好一點。這是一個嚴重的問題嗎?我不認爲我的應用程序正在使用此功能,或者這是默認情況下每個人都使用的功能嗎? – Nick

+0

編輯了這個問題 - 我希望它使「評論hack」部分更易於理解。碎片緩存並不是「開啓」或關閉的。相反,您會發現部分視圖很少改變,並通過緩存視圖的塊來加速渲染。例如,如果您有一個顯示所有頁面的下拉菜單,則通常會使用這種情況。您可以使用片段緩存來避免查詢頁面並重新呈現菜單,除非Pages.all發生更改(它使用稱爲緩存摘要的內容)。 – max

+0

這是否是一個交易斷路器取決於您的要求。 – max

-1

你是完全正確。這是它出錯

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

這裏發生了什麼

  1. 用戶請求new動作,這使得new模板
  2. 用戶提交表單,由此請求在你的控制器
  3. create行動
  4. 在你的create裏面你的行爲使你的new模板代替create當驗證失敗

因此,基本上用戶不再在new頁面上,而是在create頁面上以new呈現視圖。

最簡單的解決方案是將標題的期望值更改爲newcreate操作,因爲您重定向成功,所以您不會使用它。

+0

雖然回答的頂部是優秀它完全在「最簡單的解決辦法是將頁眉改變期望,新的和創建操作,因爲你分崩離析重定向成功,所以你不會使用它。「這裏的措辭非常混亂,但可以通過編輯來挽救。 – max