TL;DR
ActiveAdminのscope名に日本語を使いたいときは、横着せずに config/locales/ja.yml
に設定する。
問題
ActiveAdminを使っていて、scope名を日本語でベタ書きしていたら、表示されているscopeがなんだか足りない。
サンプルとして、ユーザーを登録年月別に表示したい場合を考える
hogehoge_admin/user.rb
ActiveAdmin.register User do
##### 略 #####
scope("2014年前半登録") { |scope| scope.where("created_at BETWEEN '2014-01-01' AND '2014-05-31'") }
scope("2014年後半登録") { |scope| scope.where("created_at BETWEEN '2014-06-01' AND '2014-12-31'") }
scope("2015年前半登録") { |scope| scope.where("created_at BETWEEN '2015-01-01' AND '2015-05-31'") }
scope("2015年後半登録", default: true) { |scope| scope.where("created_at BETWEEN '2015-06-01' AND '2015-12-31'") }
scope :all
##### 略 #####
end
原因
gemの中身を読んで探ってみる。
active_admin/scope.rb
module ActiveAdmin
class Scope
##### 略 ######
def initialize(name, method = nil, options = {}, &block)
@name, @scope_method = name, method.try(:to_sym)
if name.is_a? Proc
raise "A string/symbol is required as the second argument if your label is a proc." unless method
@id = ActiveAdmin::Dependency.rails.parameterize method.to_s
else
@scope_method ||= name.to_sym
@id = ActiveAdmin::Dependency.rails.parameterize name.to_s
end
@scope_method = nil if @scope_method == :all
@scope_method, @scope_block = nil, block if block_given?
@show_count = options.fetch(:show_count, true)
@display_if_block = options[:if] || proc{ true }
@default_block = options[:default] || proc{ false }
end
##### 略 ######
end
end
scope
の引数に name
, method
, option
と、block
が渡されている。
今回関係ありそうなのは name
なので、その動きを追ってみると、
@id = ActiveAdmin::Dependency.rails.parameterize name.to_s
とあるように、 name
を parameterize
したものを、 scope
の id
としているらしい。
……怪しい。のでconsoleで試してみる。
[1] pry(main)> "2014年前半登録".parameterize
=> "2014"
[2] pry(main)> "2014年後半登録".parameterize
=> "2014"
これだー!
どうやら parameterize
に日本語を渡していたのが問題だった様子。
解決策
ベタ書きせずに config/locales/ja.yml
に設定を書く。
hogehoge_admin/user.rb
ActiveAdmin.register User do
scope(:early_2014) { |scope| scope.where("created_at BETWEEN '2014-01-01' AND '2014-05-31'") }
scope(:later_2014) { |scope| scope.where("created_at BETWEEN '2014-06-01' AND '2014-12-31'") }
scope(:early_2015) { |scope| scope.where("created_at BETWEEN '2015-01-01' AND '2015-05-31'") }
scope(:later_2015, default: true) { |scope| scope.where("created_at BETWEEN '2015-06-01' AND '2015-12-31'") }
scope :all
end
config/locales/ja.yml
active_admin:
scopes:
all: すべて
early_2014: 2014年前半登録
later_2014: 2014年後半登録
early_2015: 2015年前半登録
later_2015: 2015年後半登録
雑感
ベタ打ちしないとか当たり前なんだけど、ActiveAdminのドキュメントに
scope :all, default: true
# assumes the model has a scope called ':active'
scope :active
# renames model scope ':leaves' to ':subcategories'
scope "Subcategories", :leaves
# Dynamic scope name
scope ->{ Date.today.strftime '%A' }, :published_today
# custom scope not defined on the model
scope("Inactive") { |scope| scope.where(active: false) }
# conditionally show a custom controller scope
scope "Published", if: proc { current_admin_user.can? :manage, Posts } do |posts|
posts.published
end
っていうような例があったから甘えてしまった。
日本語対応は丁寧にやろうな。
参考