9
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ActiveAdminのscope名は日語でベタ書きしてはいけない

Last updated at Posted at 2016-03-15

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

こう書くと、
bad_example
こうなる。

原因

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

とあるように、 nameparameterize したものを、 scopeid としているらしい。
……怪しい。ので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年後半登録

スクリーンショット 2016-03-15 18.20.48.png

雑感

ベタ打ちしないとか当たり前なんだけど、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

っていうような例があったから甘えてしまった。
日本語対応は丁寧にやろうな。

参考

9
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?