2016-09-14 58 views
1

在我的rails應用程序中,我使用devise進行用戶驗證。我也爲整個網站使用i18n,每個用戶都有可能在用戶設置中選擇她或他的特定語言。如果用戶使用給定的語言環境集瀏覽網站,或者它是一個訪客並使用默認語言環境,我不希望該語言環境顯示在URL中。在rspec支持文件的擴展類中獲取當前設計用戶

下面是一個例子:

一位客人使用英語(默認)版本,所以該網址是一樣的東西「anything.com/users/42」,但如果他或她在永久更改爲法語(未設置,但通過點擊法國版本的鏈接),網址變爲「anything.com/fr/users/42」。如果該用戶已登錄並選擇法語作爲默認語言,則反過來。

這是通過以下行中我application_controller

# app/controllers/application_controller.rb 
def default_locale 
    current_user ? current_user.locale : I18n.default_locale 
end 
helper_method :default_locale 

def default_url_options options={} 
    (I18n.locale.to_s.eql?(default_locale.to_s) ? { locale: nil } : { locale: I18n.locale }).merge options 
end 

此作品在我的應用程序完美無瑕的實現。

但是我在測試時遇到問題。在某些測試中,我有這樣的表述名爲League現有的模型:

visit edit_league_path(@league) 
expect(page.current_path).to eq league_path(@league) 

檢查重定向。聯盟的動作edit只允許管理員使用。

因爲我使用下面的方法之前制定我已經在用戶登錄(誰是不是管理員):

# spec/support/controller_macros.rb 
module ControllerMacros 
    def login_user *user_roles 
    before(:each) do 
     @request.env['devise.mapping'] = Devise.mappings[:user] 
     user = FactoryGirl.create(:user, *user_roles) 
     user.confirmed_at = Time.zone.now 
     user.save 
     sign_in user 
    end 
    end 
end 

廠家爲用戶創建隨機用戶隨機的語言環境。

我也有一個支持文件,即修復了RSpec的測試本地化,因爲從application_controllerdefault_url_options在RSpec的測試忽略(如討論here):

# spec/support/fix_localization.rb 
# workaround, to set default locale for ALL spec 
class ActionView::TestCase::TestController 
    def default_url_options options={} 
    { locale: I18n.locale }.merge options 
    end 
end 

class ActionDispatch::Routing::RouteSet 
    def default_url_options options={} 
    { locale: I18n.locale }.merge options 
    end 
end 

現在我的問題是,當使用默認國際化語言環境設置(例如en)的登錄用戶訪問聯盟的編輯頁面時,將被重定向,因爲他或他不允許訪問該頁面。重定向考慮從application_controllerdefault_url_options方法,並且不會重定向到/en/leagues/42(如測試期望的那樣),而是重定向到/leagues/42

我對此問題的解決方案是將spec/support/fix_localization.rb中的default_url_options方法更改爲與application_controller中的方法相同,但我無法訪問支持文件中的當前用戶。

有沒有人有關如何訪問當前用戶或其他想法或我的問題的解決方法的想法?

在此先感謝!

回答

0

我找到了一個沒有重複代碼的解決方案。從從ApplicationController繼承使用當前使用的控制器(subject

# spec/support/fix_localization.rb 
# workaround, to set default locale for ALL spec 
class ActionView::TestCase::TestController 
    def default_url_options options={} 
    subject.default_url_options options 
    end 
end 

所以,現在的default_url_options方法:我只是改變了我的spec/support/fix_localization.rb文件。

這在技術上不回答我的問題,但解決了根本問題。爲了獲得當前用戶(如最初要求),可以使用subject還有:

subject.current_user 

但這只是在支持文件,其中標的是控制器可用。