2011-02-13 67 views
79

我試圖爲sign_in操作使用名爲「設計」的不同/自定義佈局。我在devise wiki中發現了this頁面,第二個示例甚至說您可以按動作執行此操作(在這種情況下爲sign_in操作),但它沒有顯示這樣做的示例。有人在IRC告訴我,我可以試試這個:設計中的sign_in動作的不同佈局

class ApplicationController < ActionController::Base 
    protect_from_forgery 

    layout :layout_by_resource 

    def layout_by_resource 
    if devise_controller? && resource_name == :user && action_name == 'sign_in' 
     "devise" 
    else 
     "application" 
    end 
    end 
end 

但它似乎並沒有工作,因爲它仍然加載默認的應用程序佈局。我將不勝感激任何幫助。

回答

43

我想通了,但如果其他人好奇,我會在這裏保留這個問題。

這是一個愚蠢的錯誤。事實是sign_in是路徑,不是的動作。查看relevant source,我看到所需的操作是new,即創建了新的設計會話。更改我的上述代碼的條件爲:

if devise_controller? && resource_name == :user && action_name == 'new' 

工作得很好。

希望能幫助那裏的人。

+0

這不會適用於註冊#new和session#new的佈局嗎? – Ayrad 2017-02-21 20:11:08

1

只要您不知道,您也可以使用rake routes來查看您的rails應用程序中的路線以及它們映射到的動作/控制器。

new_user_registration GET /accounts/sign_up(.:format)  {:action=>"new", :controller=>"devise/registrations"} 
edit_user_registration GET /accounts/edit(.:format)   {:action=>"edit", :controller=>"devise/registrations"} 
         PUT /accounts(.:format)    {:action=>"update", :controller=>"devise/registrations"} 
         DELETE /accounts(.:format)    {:action=>"destroy", :controller=>"devise/registrations"} 
+0

謝謝,我確實知道關於耙路線,我只是沒有想過,'sign_in'可能不是實際行動的名稱,我想它會是,然後我意識到它都圍繞着這就是爲什麼它對應於新的行動。 – 2011-02-13 06:16:46

90

爲動作應用自定義佈局的另一種方法如下。

根據How To: Create custom layouts「您還可以在config/environment.rb(rails 2)或config/application.rb(rails 3)中使用回調來設置特定Devise控制器的佈局,這需要在to_prepare回調,因爲它在生產中和開發中的每個請求之前執行一次。「

config.to_prepare do 
    Devise::SessionsController.layout "devise" 
    Devise::RegistrationsController.layout proc{ |controller| user_signed_in? ? "application" : "devise" } 
    Devise::ConfirmationsController.layout "devise" 
    Devise::UnlocksController.layout "devise"    
    Devise::PasswordsController.layout "devise"   
end 

通常在登錄頁面和不需要認證的頁面之間進行佈局區分,所以上面的方法大多數時候都是有效的。但是,我也嘗試過使用action_name幫手來設置特定的操作佈局和它的工作般的魅力:

config.to_prepare do 
    Devise::SessionsController.layout proc{ |controller| action_name == 'new' ? "devise" : "application" } 
end 

我覺得這是更好的和基於色器件控制器/動作而不是內置的方式來改變佈局在ApplicationController中創建一個幫助器。

+3

另外,不要忘記每次在config文件夾中對任何文件進行更改時重新啓動服務器,在這種情況下,config/application.rb for Rails3或config/environment.rb for Rails 2,以使更改生效。 – Zeeshan 2011-08-21 17:13:46

+0

**小心**我在rails 3.1中試過這種方法,它使資產文件夾中資源的加載速度明顯變慢。這不會影響生產服務器,但是當您擁有多個css/js文件時,您會注意到它。 – Gazler 2012-02-17 16:55:18

+0

在上面的例子中,是否可以爲單獨的設計資源配置佈局(例如,讓我們假設我們有兩種不同類型的設計用戶,並且每個都需要它們自己的佈局) – ckarbass 2012-06-30 01:37:23

61

我剛剛創建了app/views/layouts/devise/sessions.html.erb並將我的佈局放在那裏。

0

這裏是一個班輪,誰想要都制定行動,以使用新的佈局:

class ApplicationController < ActionController::Base 
    protect_from_forgery 

    layout Proc.new { |controller| controller.devise_controller? ? 'devise' : 'application' } 
end 
8

這是我做到了。如果用戶必須登錄,我想要一個不同的佈局,但如果用戶必須編輯他/她的個人資料,則需要不同的佈局。

我正在使用Rails 4.1。1

在應用控制器,補充一點:

class ApplicationController < ActionController::Base 
    # Prevent CSRF attacks by raising an exception. 
    # For APIs, you may want to use :null_session instead. 
    protect_from_forgery with: :exception 
    before_action :configure_permitted_parameters, if: :devise_controller? 

    layout :layout_by_resource 

    # Define the permitted parameters for Devise. 
    protected 

    def configure_permitted_parameters 
    devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:firstname, :lastname, :email, :password, :password_confirmation)} 
    devise_parameter_sanitizer.for(:account_update) { |u| u.permit(:avatar, :firstname, :lastname, :email, :password, :password_confirmation, :current_password) } 
    end 

    def layout_by_resource 
    if devise_controller? and user_signed_in? 
     'dashboard' 
    else 
     'application' 
    end 
    end 
end 
5

驚訝地沒有看到這個答案的任何地方,但你也可以這樣做:

在routes.rb中,改變你的色器件的配置看是這樣的:

devise_for :users, controllers: { 
    sessions: 'sessions' 
    } 

然後在app /控制器/ sessions_controller.rb

class SessionsController < Devise::SessionsController 
    layout 'devise', only: [:new] 
end 

如果您需要在任何Devise控制器中執行額外的邏輯覆蓋,這將特別有用。

7

最簡單的解決方案是在app/views/layouts文件夾中創建一個名爲devise.html.haml的佈局。而Rails的魔術則負責其餘部分。

app/views/layouts/devise.html.haml