2012-03-23 56 views
4

在我的應用程序中,我有兩個來自兩個控制器的登錄表單,這兩個登錄表單都將通過Devise :: SessionsController進行簽名,問題是在成功登錄(或失敗)之後,我需要重定向到特定於控制器的不同頁面。我怎樣才能做到這一點。我現在有這在我的設計:: SessionsController,這登錄後如何重定向到不同的頁面(基於某個參數)?

class SessionsController < Devise::SessionsController 
    def create 
     resource = warden.authenticate!(:scope => resource_name, :recall => "#{controller_path}#failure") 
     return sign_in_and_redirect(resource_name, resource) 
     end 

     def sign_in_and_redirect(resource_or_scope, resource=nil) 
     scope = Devise::Mapping.find_scope!(resource_or_scope) 
     resource ||= resource_or_scope 
     sign_in(scope, resource) unless warden.user(scope) == resource 
     redirect_to dashboard_path 
     end 

     def failure  
     redirect_to index_path 
     end 
end 

回答

12

在應用控制器

before_filter :store_location 
    def store_location 
    unless params[:controller] == "devise/sessions" 
     url = #calculate the url here based on a params[:token] which you passed in 
     session[:user_return_to] = url 
    end 
    end 

    def stored_location_for(resource_or_scope) 
    session[:user_return_to] || super 
    end 

    def after_sign_in_path_for(resource) 
    stored_location_for(resource) || root_path 
    end 
0

您可以通過在你的控制,要自定義此重定向路徑定義after_sign_in_path_for方法做到這一點。

+0

是的,但問題是我如何提供參數after_sign_in_path_for告訴下一步該去哪裏? – Rn2dy 2012-03-23 07:26:44

+0

比你應該創建自己的會話控制器,並在設計配置中覆蓋它,就像這樣:'devise_for:users,:controllers => {:sessions =>「users/sessions」}'。在此控制器中,您可以將可選參數傳遞給'after_sign_in_path_for',並在需要時再檢查它們。此外,您可以將會話參數傳遞給會話並在自定義'after_sign_in_path_for'中檢查會話變量,或者可以使用'Thread.current'來傳遞這個附加參數。 – Hck 2012-03-23 07:29:06

+0

謝謝Hck,我想這個問題真的是我應該如何定義這個參數,我應該在哪裏將這個參數傳遞給after_sign_in_path,請幫助。 – Rn2dy 2012-03-23 07:35:38

2

如果有人還在尋找一個變通。我能夠來解決這個問題:

首先,創建一個會話控制器從Devise::SessionsController

class SessionsController < Devise::SessionsController 

    def new 
    get_pre_login_url(request.referer) 
    super 
    end 

    def create 
    @@referer_url 
    super 
    end 

private 

    def get_pre_login_url(url) 
    @@referer_url = url 
    end 

    def after_sign_in_path_for(resource) 
    # @@referer_url 
    sign_in_url = url_for(:action => 'new', :controller => 'sessions', :only_path => false, :protocol => 'http') 
    if @@referer_url == sign_in_url 
     super 
    else 
     stored_location_for(resource) || @@referer_url || root_path 
    end 
    end 

end 

繼承你會發現我設置類變量(@@variable_name),這我並不熱衷於,但這是我在嘗試各種其他方式解決這個問題4小時後想出來的。我也試圖小心,不要太多地使用Devise的控制器,並使用super,只包括我關心的操作。

接下來,在路徑中,您現在可以將Devise的默認值指向上面的Controller。你不需要它完全像下面爲devise_for,只是部分引用controllers: { sessions: "sessions" }

MyPortfolio::Application.routes.draw do 

    devise_for :users, path_names: { sign_in: "login", 
            sign_out: "logout" }, 
        controllers: { omniauth_callbacks: "omniauth_callbacks", 
            sessions: "sessions" } 

    resources :posts do 
    resources :comments 
    end 

    resources :projects do 
    resources :comments 
    end 

    resources :users 

    root :to => 'home#index' 

    get 'login' => 'devise/sessions#new' 
    get 'about_me' => 'about#index' 
end 

它可能不是周圍的DRYest的解決方案,但它是唯一一個我能拿出來將重定向指向原始頁面而不是根目錄或無限循環。

相關問題