2017-04-19 22 views
1

我想讓一個我的ruby on rails Web應用程序的頁面無法訪問我的一個STI模型類型。我有兩個繼承自User的typeA和typeB模型。我在用戶表中使用了列類型來實現STI。我正在使用Devise gem進行用戶會話。我希望我的typeA用戶無法訪問一個網頁'http://localhost:3000/rate'。無論何時用戶登錄「typeA」類型的用戶,他都沒有選擇查看鏈接「費率」的選項。但我也不希望他能通過鏈接「http://localhost:3000/rate」訪問該頁面。如果他試圖通過該鏈接訪問它,我想簽署他並讓他再次登錄。 我通過使用Controller中的一段代碼來處理這個問題,並使用'rate'的具體方法。如何使我的基於STI的設計用戶模型類型之一的某些頁面無法訪問我的Ruby on Rails應用程序?

def rate 
    if current_user.type == "typeA" 
    sign_out(current_user) 
    redirect_to new_user_session_path 
    else 
    #Code for User of typeB 
    end 
end 

這是工作,但我想知道這是否可以使用的before_filter一種更好的方式來完成:的authenticate_user!或別的東西 現在我的before_filter部分看起來像這樣

before_filter :authenticate_user!, except: [:index, :show] 

有什麼辦法,我可以做出改變到上代碼來實現該功能。
P.S:也許這可以做得更好,如果我曾經使用角色或其他像CanCan/Pundit這樣的寶石,但我沒有太多時間提交我的項目,所以我現在不想進入這一切。與您的控制器

class ApplicationController 

    before_action :authenticate_user! 

    def authorize_user! 
    if current_user.type == "typeA" 
     sign_out(current_user) 
     redirect_to new_user_session_path 
    end 
    end 

end 

回答

1

您可以在要限制訪問的控制器上添加另一個before_filter,以確認您的STI用戶類型,而不需要過濾設備的authenticate_user!過濾器。

application_controller.rb

class ApplicationController < ActionController::Base 

    def confirm_user_type(user_type) 
    redirect_to new_user_session_path unless current_user.is_a?(user_type) 
    end 

end 

pages_controller.rb

class PagesController < ApplicationController 
    # must be authenticated to access 
    before_filter :authenticate_user! 
    # must be user of TypeA to access 
    before_filter { |c| c.confirm_user_type(TypeA) } 

    def rate 
    ... 
    end 
end 

然後,您可以使用相同的過濾器before_filter { |c| c.confirm_user_type(TypeB) }性病用戶type: 'TypeB'

+0

我不希望整個控制器無法輸入A。我只想要'rate'頁面無法訪問到他。還有其他的方法,如索引,創建,顯示等,他應該仍然可以訪問它。我如何把它放在我的代碼中? –

+0

你可以使用'only:'選項來做'before_filter {| c | c.confirm_user_type(TypeA)},:only => [:rate]' – sa77

+0

我現在得到的錯誤頁面是/Users/Suvajit/Documents/Code/Rails/Mckenzie/app/controllers/dishes_controller.rb:4:syntax錯誤,意外':',期待keyword_end .confirm_user_type(TypeA)}:only => [:rate]^ 我使用的代碼是 'before_filter {| c | c.confirm_user_type(TypeA)},:only => [:rate]' –

0

試試這個

class SomeController < ApplicationController 

    before_action :authorize_user!, except: [:index, :show] 

    def top_secret 
     ... 
    end 

end 

我相信,如果一個before_action(爲的before_filter的新名稱)渲染或重定向,該行動將不會被處理。

+0

這是行不通的。現在,無論何時我嘗試訪問即使允許typeA訪問的頁面,它都會將其簽出。另外,當我退出並試圖訪問'http:// localhost:3000/rate'時,它會顯示一個Rails錯誤頁面,指出未知變量'current_user.type'。通過我之前完成的代碼,當我退出並嘗試訪問「http:// localhost:3000/rate」時,它只會刷新頁面,並顯示Devise Flash消息,指出「您需要登錄或者在繼續'之前註冊',這對我來說很好。無論如何感謝您的回答。 –

+0

啊沒有認識到authenticate_user!是標準設計,所以你不應該壓倒它。我認爲這裏的代碼應該工作。它將首先進行身份驗證以設置current_user,然後進行授權。 – mahemoff

相關問題