求助:ActiveAdmin与i18n-active_record冲突,如何让前者脱离后者运行
我之前也踩过一模一样的坑!i18n-active_record会把项目的翻译源默认导向数据库存储,但ActiveAdmin的界面文本依赖的是本地yaml配置文件里的翻译,两者一碰撞就会出现ActiveAdmin全是「翻译缺失」提示的情况。下面分享几个亲测有效的解决办法,帮你让ActiveAdmin脱离i18n-active_record正常运行:
方法一:给ActiveAdmin单独切换i18n后端
在ActiveAdmin的初始化文件config/initializers/active_admin.rb中添加以下代码,让每个ActiveAdmin请求临时切换到默认的yaml后端,请求结束后再切回数据库后端:
ActiveAdmin.setup do |config| # 保留你原本的其他配置... config.before_action do # 先保存原来的数据库后端 original_backend = I18n.backend # 切换到Simple后端(加载yaml文件的默认后端) I18n.backend = I18n::Backend::Simple.new # 加载ActiveAdmin需要的翻译文件 I18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}')] I18n.reload! # 请求结束后务必切回原来的后端,不影响业务逻辑的翻译 ensure I18n.backend = original_backend end end end
这个方法的好处是完全隔离了ActiveAdmin和业务逻辑的翻译源,两边各用各的,不会互相干扰。
方法二:配置i18n链式后端(推荐)
如果不想频繁切换后端,可以直接把i18n的后端设置为链式结构,让系统优先从yaml文件找翻译,找不到再去数据库查找。在config/initializers/i18n.rb中配置:
# 链式后端:先查Simple(yaml),再查ActiveRecord(数据库) I18n.backend = I18n::Backend::Chain.new( I18n::Backend::Simple.new, I18n::Backend::ActiveRecord.new ) # 加载所有本地翻译文件 I18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}')] I18n.reload!
这个方案更省心,ActiveAdmin需要的界面翻译会优先从yaml文件读取,而你业务逻辑里用i18n-active_record管理的翻译依然正常从数据库取,完美兼容两者。
方法三:将ActiveAdmin翻译导入数据库
如果你更倾向于统一用数据库管理所有翻译,可以写一个rake任务,把config/locales/active_admin/目录下的yaml翻译批量导入到i18n-active_record的translations表中。不过这个方法维护成本较高,后续ActiveAdmin版本更新时还需要同步翻译,不是特别推荐。
内容的提问来源于stack exchange,提问作者Haseeb Ahmad

