【发布时间】:2016-09-14 21:19:04
【问题描述】:
在我的 rails 应用程序中,我使用 devise 进行用户身份验证。我还在整个网站上使用 i18n,每个用户都可以在用户设置中选择她或他的特定语言。如果用户使用给定的区域设置浏览网站,或者它是访客并使用默认区域设置,我不希望该区域设置显示在 url 中。
这是一个例子:
客人使用英文(默认)版本,因此网址类似于“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_controller 的 default_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
现在我的问题是,当使用默认 i18n 区域设置(例如 en)的登录用户访问联赛的编辑页面时,会被重定向,因为不允许她或他访问该页面。重定向会考虑来自application_controller 的default_url_options 方法,并且不会重定向到/en/leagues/42(正如测试所期望的那样),而是重定向到/leagues/42。
我对此问题的解决方案是将spec/support/fix_localization.rb 中的default_url_options 方法更改为与application_controller 中的相同,但我无法访问支持文件中的当前用户。
有没有人知道如何访问当前用户或其他想法或解决我的问题的方法?
提前致谢!
【问题讨论】:
标签: ruby-on-rails rspec devise internationalization rails-i18n