2014/08/03

Redmineプラグイン開発における ActiveModel 使用上の注意点

先のエントリ: tail -f pinzo.log: ActiveSupport::Concern の included と ClassMethods の順序 に関連してます。

Redmine のプラグインでちょっと凝ったことをしようとすると、ActiveModel を使いたくなることがある。
ActiveModel のメリットの一つに ActiveRecord と同様のバリデーションを手軽に定義できることがある。
しかし、Redmine 本体の locales/ja.yml には ActiveModel の設定は入っていないので、プラグインの locales/ja.yml に書くことになる。
その際、たいてい Redmine 本体の locales/ja.yml から ActiveRecord 用の設定をコピーしてくることになりがち。
ja:
activemodel:
errors:
messages:
inclusion: "は一覧にありません。"
exclusion: "は予約されています。"
invalid: "は不正な値です。"
confirmation: "が一致しません。"
accepted: "を受諾してください。"
empty: "を入力してください。"
blank: "を入力してください。"
too_long: "は%{count}文字以内で入力してください。"
too_short: "は%{count}文字以上で入力してください。"
wrong_length: "は%{count}文字で入力してください。"
taken: "はすでに存在します。"
not_a_number: "は数値で入力してください。"
not_a_date: "は日付を入力してください。"
greater_than: "は%{count}より大きい値にしてください。"
greater_than_or_equal_to: "は%{count}以上の値にしてください。"
equal_to: "は%{count}にしてください。"
less_than: "は%{count}より小さい値にしてください。"
less_than_or_equal_to: "は%{count}以下の値にしてください。"
odd: "は奇数にしてください。"
even: "は偶数にしてください。"
view raw locales_ja.yml hosted with ❤ by GitHub
こんな感じに。

ここまではいい。

問題は、ここからちょいと修正を入れてしまうことにある。
ちょっと文言をいじってしまうと ActiveModel のデフォルトの文言を上書きするということになる。
これを複数プラグインでやってしまった場合、さてあなたのプラグインではどんなエラーが表示されるだろう?
これらの辞書ファイルはマージされるので、ロード順や入れてあるプラグインの状態により変わってしまい想定できなくなる。
文言をテストで使用していたりしたら、テストが失敗してしまう。
それを避けるためにも、先のエントリで書いたようなテクニックを利用して、自分のプラグインの ActiveModel が使用するセクションを独立させてあげよう。
module MyPlugin::Model
extend ActiveSupport::Concern
included do
__send__(:include, ActiveModel::Conversion)
__send__(:include, ActiveModel::Validations)
extend ActiveModel::Naming
extend ActiveModel::Translation
class << self
alias_method_chain :i18n_scope, :my_plugin_model
end
end
module ClassMethods
def i18n_scope_with_my_plugin_model
:my_plugin_model
end
end
def persisted?
false
end
end
ja:
my_plugin_model:
errors:
messages:
inclusion: "は一覧にありません。"
exclusion: "は予約されています。"
invalid: "は不正な値です。"
confirmation: "が一致しません。"
accepted: "を受諾してください。"
empty: "を入力してください。"
blank: "を入力してください。"
too_long: "は%{count}文字以内で入力してください。"
too_short: "は%{count}文字以上で入力してください。"
wrong_length: "は%{count}文字で入力してください。"
taken: "はすでに存在します。"
not_a_number: "は数値で入力してください。"
not_a_date: "は日付を入力してください。"
greater_than: "は%{count}より大きい値にしてください。"
greater_than_or_equal_to: "は%{count}以上の値にしてください。"
equal_to: "は%{count}にしてください。"
less_than: "は%{count}より小さい値にしてください。"
less_than_or_equal_to: "は%{count}以下の値にしてください。"
odd: "は奇数にしてください。"
even: "は偶数にしてください。"
こんな感じに。(my_plugin 部分にはあなたのプラグインの一意な識別子を指定しましょう。)

それでは、今日もよい日曜開発を

0 件のコメント :

コメントを投稿