2015/10/30

自作gemのテストを test-unit で行う

久しぶりに自作 gem でも作るかと bundle gem -t とすると自動的に spec フォルダと .rspec が作成された。
いやいや、test-unit 使いたいんだってば。
仕方ないので自分で設定することに
gemspec に spec.add_development_dependency 'test-unit' を追加し、Rakefile にこんな感じに設定を書くだけだった。

2015/10/27

自作クラスの配列同士で引き算を正しく動作させるには

自作の配列で引き算を行おうとしたら、==のオーバーライドだけでは足りず、eql?hashのオーバーライドが必要だった。

2014/11/10

Yosemite にした

日曜夜に MBA を Yosemite にアップグレードした。
/usr/local だなんだと言われているけど、寝ている間に終わればいいやと放置したので特に何もせず。
起きたら無事に終わっていたし、今使っていて何も問題ない。
ただ、UI は前のほうがいいな。なんかちゃちく見える。
左上の信号みたいなボタン3つの主張が激しくなった。
透明感のあるメタリックな感じが良かったのに、パステルなペイント風になってがっかりだ。

2014/09/11

さくらVPSの Ubuntu12.04 を 14.04 にした

さくらVPSにログインするとアップグレードできるよって通知が出ていたので、14.04 にアップグレードしやした。
盛大にハマった....

コマンド叩く

$ do-release-upgrade
The upgrade has aborted. The upgrade needs a total of 55.6 M free space on disk '/boot'. Please free at least an additional 12.7 M of disk space on '/boot'. Empty your trash and remove temporary packages of former installations using 'sudo apt-get clean'.
いきなり容量が足りないときた。
/boot以下のファイルのうち、最新バージョン以外を削除して再度実行すればOKだった。
何度か、設定ファイルなどを最新のに上書きするかい?って聞かれるけど、おこのみで。
しないほうが無難だとは思う。

バージョンの確認

git はソースから入れた 2.1.0 のまま。
前回と同じくRubyはリポジトリのものに置き換えられて 1.9.3 になっていたので入れ替えた。
$ mv /usr/bin/erb{,.bak}
$ mv /usr/bin/gem{,.bak}
$ mv /usr/bin/irb{,.bak}
$ mv /usr/bin/rake{,.bak}
$ mv /usr/bin/rdoc{,.bak}
$ mv /usr/bin/ri{,.bak}
$ mv /usr/bin/ruby{,.bak}
$ mv /usr/bin/testrb{,.bak}
$ ln -sfn /opt/ruby/ruby-2.1.2/bin/* /usr/bin
ようやく Ubuntu でも 1.9.3 がデフォルトになったのか。めでたい。

Passengerのアップデート

Apacheのバージョンが上がったので、Passenger も再インストール。
$ gem install passenger
/opt/ruby/ruby-2.1.2/bin/passenger-install-apache2-module を実行 * To install Apache 2 development headers: Please install it with apt-get install apache2-threaded-dev * To install Apache Portable Runtime (APR) development headers: Please install it with apt-get install libapr1-dev * To install Apache Portable Runtime Utility (APU) development headers: Please install it with apt-get install libaprutil1-dev
言われるままにインストールする。
$ aptitude install apache2-threaded-dev libapr1-dev libaprutil1-dev
passengerモジュールをインストール。
$ passenger-install-apache2-module
apache2: Syntax error on line 140 of /etc/apache2/apache2.conf: Syntax error on line 1 of /etc/apache2/mods-enabled/passenger.load: Cannot load /opt/ruby/ruby-2.1.2/lib/ruby/gems/2.1.0/gems/passenger-4.0.45/buildout/apache2/mod_passenger.so into server: /opt/ruby/ruby-2.1.2/lib/ruby/gems/2.1.0/gems/passenger-4.0.45/buildout/apache2/mod_passenger.so: undefined symbol: unixd_config apache2: Syntax error on line 140 of /etc/apache2/apache2.conf: Syntax error on line 1 of /etc/apache2/mods-enabled/passenger.load: Cannot load /opt/ruby/ruby-2.1.2/lib/ruby/gems/2.1.0/gems/passenger-4.0.45/buildout/apache2/mod_passenger.so into server: /opt/ruby/ruby-2.1.2/lib/ruby/gems/2.1.0/gems/passenger-4.0.45/buildout/apache2/mod_passenger.so: undefined symbol: unixd_config Your Apache installation might be broken
なぜかビルド出来ない。調べてみると unixd_config は ap_unixd_config にリネームされたらしいが、決定的な情報が出てこず、ハマる。悩む。
で、よーーーーーーーーく考えてみると、passenger.load でエラーが出ているけど、新しい passenger 入れるんだからいらんだろ!ということで、passenger.load と passenger.conf の中身をコメントアウトしたらビルド通った。

Redmine

前回のアップグレードでは、RMagicがおかしなことになっていたので、確認してみる。
RMagic とか Redmine 以前に、ERR_SSL_PROTOCOL_ERROR とか言われて接続できていないんですけどー。
/etc/apache2/sites-available/default-ssl.conf から /etc/apache2/sites-enabled/000-default-ssl.conf とかシンボリックリンクを貼ると Redmine ではなくデフォルトページだが表示されるので、Redmine 用の設定が読み込まれていないっぽい。
調べてみると server - Why not work Apache virtual hosts on Ubuntu 14.04? - Ask Ubuntu がヒット。
Apache2.4から .conf 拡張子が必要になったらしい。
$ rm /etc/apache2/sites-enabled/001-redmine
$ mv /etc/apache2/sites-available/redmine{,.conf}
$ ln -s /etc/apache2/sites-available/redmine.conf /etc/apache2/sites-enabled/001-redmine.conf
$ service apache2 restart
AH00548: NameVirtualHost has no effect and will be removed in the next release /etc/apache2/sites-enabled/001-redmine.conf:1
ちゃんと読み込まれたらしい。警告が出たので、対応もした。

再度アクセスしたら、今度は You don't have permission to access / on this server. とか言われる。今まではこれで動いとってん!
/var/log/apache2/error.log には AH01630: client denied by server configuration: /var/lib/rails/redmine/public と出力されている。
redmine.conf にパーミッション設定をすればよさげ。
<VirtualHost *:443>
  ServerName xxx.mkt-sys.jp:443
  DocumentRoot /var/lib/rails/redmine/public
  <Directory /var/lib/rails/redmine/public/>
    Options FollowSymLinks
    AllowOverride None
    Order allow,deny
    Allow from all
  </Directory>
  SSLCertificateFile    /etc/apache2/cert/ssl-cert.pem
  SSLCertificateKeyFile /etc/apache2/cert/ssl-cert.key
  PassengerEnabled on
</VirtualHost>
しかし、これでも動かない。わけわからん。
ここで再びネットの海を彷徨い おほ。2.4系じゃ .htaccess ファイルの許可の仕方も変わってるんだなあ - 電気ウナギ的○○ を発見する。
<VirtualHost *:443>
  ServerName xxx.mkt-sys.jp:443
  DocumentRoot /var/lib/rails/redmine/public
  <Directory /var/lib/rails/redmine/public/>
    Options FollowSymLinks
    AllowOverride None
    Require all granted
  </Directory>
  SSLCertificateFile    /etc/apache2/cert/ssl-cert.pem
  SSLCertificateKeyFile /etc/apache2/cert/ssl-cert.key
  PassengerEnabled on
</VirtualHost>
とせんとイカンらしい。これでようやくRedmineが表示された。

ImageMagickとRMagick

Redmineを確認すると案の定下記の ImageMagick 関連がエラーになっていた。
  • RMagickが利用可能 (オプション)
  • ImageMagickのconvertコマンドが利用可能 (オプション)
前回の用にソースから再度ビルドしてもいいのだが、どうやら apt に入っている ImageMagick も新しくなって、RMagick をすんなり入れられるらしいので、入れ替える。
/usr/bin から ImageMagick 関連のシンボリックリンクを削除した後に ImageMagick と RMagick を入れ替える。
$ aptitude install imagemagick libmagick++-dev
$ cd /var/lib/rails/redmine
$ bundle exec gem uninstall rmagick
$ bundle install
これで、"ImageMagickのconvertコマンドが利用可能 (オプション)" は解決。
RMagick については以前の経験により調査する。
$ bundle exec rails c production
irb(main):001:0> require 'RMagick'
LoadError: liblcms.so.1: cannot open shared object file: No such file or directory - /var/lib/rails/redmine-2.5.2/vendor/bundle/ruby/2.1.0/extensions/x86_64-linux/2.1.0-static/rmagick-2.13.2/RMagick2.so from /var/lib/rails/redmine-2.5.2/vendor/bundle/ruby/2.1.0/gems/activesupport-3.2.19/lib/active_support/dependencies.rb:251:in `require' from /var/lib/rails/redmine-2.5.2/vendor/bundle/ruby/2.1.0/gems/activesupport-3.2.19/lib/active_support/dependencies.rb:251:in `block in require' from /var/lib/rails/redmine-2.5.2/vendor/bundle/ruby/2.1.0/gems/activesupport-3.2.19/lib/active_support/dependencies.rb:236:in `load_dependency' from /var/lib/rails/redmine-2.5.2/vendor/bundle/ruby/2.1.0/gems/activesupport-3.2.19/lib/active_support/dependencies.rb:251:in `require' from /var/lib/rails/redmine-2.5.2/vendor/bundle/ruby/2.1.0/gems/rmagick-2.13.2/lib/RMagick.rb:11:in `<top (required)>' from /var/lib/rails/redmine-2.5.2/vendor/bundle/ruby/2.1.0/gems/activesupport-3.2.19/lib/active_support/dependencies.rb:251:in `require' from /var/lib/rails/redmine-2.5.2/vendor/bundle/ruby/2.1.0/gems/activesupport-3.2.19/lib/active_support/dependencies.rb:251:in `block in require' from /var/lib/rails/redmine-2.5.2/vendor/bundle/ruby/2.1.0/gems/activesupport-3.2.19/lib/active_support/dependencies.rb:236:in `load_dependency' from /var/lib/rails/redmine-2.5.2/vendor/bundle/ruby/2.1.0/gems/activesupport-3.2.19/lib/active_support/dependencies.rb:251:in `require' from (irb):1 from /var/lib/rails/redmine-2.5.2/vendor/bundle/ruby/2.1.0/gems/railties-3.2.19/lib/rails/commands/console.rb:47:in `start' from /var/lib/rails/redmine-2.5.2/vendor/bundle/ruby/2.1.0/gems/railties-3.2.19/lib/rails/commands/console.rb:8:in `start' from /var/lib/rails/redmine-2.5.2/vendor/bundle/ruby/2.1.0/gems/railties-3.2.19/lib/rails/commands.rb:41:in `<top (required)>' from script/rails:6:in `require' from script/rails:6:in `<main>'
liblcms.so.1 が見つからないらしい。locate しても確かにいない。
apt で入れたのに、ライブラリ足りないってどーゆーことよ。
依存関係を調べてみる。
$ ldd vendor/bundle/ruby/2.1.0/gems/rmagick-2.13.2/lib/RMagick2.so
linux-vdso.so.1 => (0x00007fff01ffe000) libMagickCore.so.5 => /usr/local/lib/libMagickCore.so.5 (0x00007f6be578c000) libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f6be556e000) libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f6be5267000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f6be4ea1000) liblcms.so.1 => not found libtiff.so.4 => not found libfreetype.so.6 => /usr/lib/x86_64-linux-gnu/libfreetype.so.6 (0x00007f6be4bfd000) libjasper.so.1 => /usr/lib/x86_64-linux-gnu/libjasper.so.1 (0x00007f6be49a6000) libjpeg.so.62 => /usr/lib/x86_64-linux-gnu/libjpeg.so.62 (0x00007f6be4780000) libpng12.so.0 => /lib/x86_64-linux-gnu/libpng12.so.0 (0x00007f6be455a000) libXext.so.6 => /usr/lib/x86_64-linux-gnu/libXext.so.6 (0x00007f6be4348000) libSM.so.6 => /usr/lib/x86_64-linux-gnu/libSM.so.6 (0x00007f6be413f000) libICE.so.6 => /usr/lib/x86_64-linux-gnu/libICE.so.6 (0x00007f6be3f23000) libX11.so.6 => /usr/lib/x86_64-linux-gnu/libX11.so.6 (0x00007f6be3bee000) libbz2.so.1.0 => /lib/x86_64-linux-gnu/libbz2.so.1.0 (0x00007f6be39dd000) libxml2.so.2 => /usr/lib/x86_64-linux-gnu/libxml2.so.2 (0x00007f6be3677000) libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f6be345e000) libgomp.so.1 => /usr/lib/x86_64-linux-gnu/libgomp.so.1 (0x00007f6be324e000) libltdl.so.7 => /usr/lib/x86_64-linux-gnu/libltdl.so.7 (0x00007f6be3044000) libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f6be2e40000) /lib64/ld-linux-x86-64.so.2 (0x00007f6be607c000) libjpeg.so.8 => /usr/lib/x86_64-linux-gnu/libjpeg.so.8 (0x00007f6be2bea000) libuuid.so.1 => /lib/x86_64-linux-gnu/libuuid.so.1 (0x00007f6be29e5000) libxcb.so.1 => /usr/lib/x86_64-linux-gnu/libxcb.so.1 (0x00007f6be27c5000) liblzma.so.5 => /lib/x86_64-linux-gnu/liblzma.so.5 (0x00007f6be25a3000) libXau.so.6 => /usr/lib/x86_64-linux-gnu/libXau.so.6 (0x00007f6be239e000) libXdmcp.so.6 => /usr/lib/x86_64-linux-gnu/libXdmcp.so.6 (0x00007f6be2198000)
なんと liblcms.so.1 だけでなく、libtiff.so.4 も見つからないらしい。おろろーん。
aptitude でみてみると libtiff5 や libcmls2 は入っている。
lrwxrwxrwx 1 root root     17 Jan 16  2014 /usr/lib/x86_64-linux-gnu/liblcms2.so -> liblcms2.so.2.0.5
lrwxrwxrwx 1 root root     17 Jan 16  2014 /usr/lib/x86_64-linux-gnu/liblcms2.so.2 -> liblcms2.so.2.0.5
-rw-r--r-- 1 root root 346928 Jan 16  2014 /usr/lib/x86_64-linux-gnu/liblcms2.so.2.0.5
# 省略
lrwxrwxrwx 1 root root     16 May  6 04:39 /usr/lib/x86_64-linux-gnu/libtiff.so -> libtiff.so.5.2.0
lrwxrwxrwx 1 root root     16 May  6 04:39 /usr/lib/x86_64-linux-gnu/libtiff.so.5 -> libtiff.so.5.2.0
-rw-r--r-- 1 root root 467208 May  6 04:39 /usr/lib/x86_64-linux-gnu/libtiff.so.5.2.0
ライブラリのファイルもあるので、多少バージョンが違うかもしれないが強引にこれらにリンクさせてみる。
$ cd /usr/lib/x86_64-linux-gnu/
$ ln -s liblcms2.so liblcms.so.1
$ ln -s libtiff.so.5 libtiff.so.4
Redmine を再起動して確認してみると、"ImageMagickのconvertコマンドが利用可能 (オプション)" もOKマークに変わっている。
念のため、動かしてみる。
Redmine では、RMagick はガントチャートの PNG のために使用されているので、PNG 表示してみると無事に表示されたが、日本語が文字化けした。
ガントチャートをPNG形式の画像に出力すると文字化けする — Redmine.JP によると、日本語フォントを設定しないといけないらしい。
そもそもインストールしていないのでインストールして設定する。
$ aptitude install fonts-ipaexfont
$ vim /var/lib/rails/redmine/config/configration.yml
#=> rmagick_font_path に /usr/share/fonts/truetype/fonts-japanese-gothic.ttf を指定
するとすんなり PNG でも日本語が表示された。
ということで、とりあえず問題は解決したと思われる。
しかし、もっと本質的な解決方法があると思うなぁ、でも疲れたので今回はここまで。
前回より苦戦しないかと思ったらとんでもない、ドはまりしてだいぶ時間がかかった。

2014/08/29

アソシエーションで定義された属性の名前を取得する

テーブル列である属性を取得するには ActiveRecord::Base#attribute_names で取得できるけど、has_many などで定義された属性名は取得できない。
アソシエーションで定義された属性は ActiveRecord::Base#reflections 経由で取得できる。 ActiveRecord::Base#attribute_names は文字列の配列を返すけど、こっちはシンボルの配列を返す。

2014/08/28

更新ないけど維持はしてるよ

少し前ですがRails4.0.9と4.1.5がリリースされたので、自作の Rails 関連の gem がちゃんと動くかな?と Travis の Job を動かしてみたら、まあ無事に全部通ったんです。
travis-ci.org に行って、Restart ボタンを押すだけの簡単なお仕事。
それはいいんだけど、Ruby や Rails 界隈では更新のない gem は使わない、使用を控える、同じ機能なら新しい方、開発が活発な方という指針が一部あって(そんな気がする)、せっかく最新バージョンでも動くのにバグフィックスや機能追加がない、つまり更新がないだけで使われない gem も出てくるわけです。
さすがにあまりないだろうけど、更新がないだけで後発の同じ機能を持つ車輪の再発明 gem の方を優先されたら作者としては悔しいわけです。動くのに。
でも「travis-ci.org に行って、Restart ボタンを押すだけの簡単なお仕事」だけだと、Github にも Rubygems.org にも維持してる証拠が残らないんですよね。
gem の選別してる時に、Github で最終更新日や README.md に載ってる CI のバッジでの最終ビルド結果は見ても、そこから CI のサイトで、最新の Rails や Ruby のバージョンでビルドしてることまで見るんだろうか?
自分は毎回そこまで見ていない気がするし、そうしてくれたら嬉しいけど、そこまでを分化としていくのは難しい気がする。
となると、やはり何らかの証拠を作者が残すしかない。

1. バージョン上げる

確実だし、Github にも Rubygems.org にも証拠が残る。
自分の基本的なバージョン指針は「0.0.1 が開発中、たまに 0.5.x とか 0.9.x で Pre-release や RC を経て、最初の想定していた機能ができたら、1.0.0 としてリリースし、その後は、機能追加でマイナーバージョンをあげて、バグフィックスなどの機能を追加しない修正はリビジョン(tiny)を上げる」というものなんだけど、この場合リビジョン上げるていいのかどうか悩む。
ソースコードに変更がないのにいたずらにバージョンを上げるべきじゃないと思うし、バージョンあげてしまうと利用者全員に自分と同じような作業が発生する可能性がある。なのでバージョンは上げたくない。

2. CIを空コミットで回す

Github には証拠が残る。Rubygems.org はそのまんま。
コミットメッセージに「Railsバージョンアップによる確認のための空コミットだよ」みたいなコメントを残しておけばわかりやすい。

3. README.mdにログを残す

Github には証拠が残る。Rubygems.org はそのまんま。
基本的に Changelog は書いてるので、そこに追記するか、Change してねーだろってんなら Activity log みたいなセクションを設けて記述する。
Github まで行って README.md 読まない奴はあまりおらんだろうという想定。
ファイルの最終更新まで変更されるし自動的にコミットも伴うから、空コミットより訪問者にわかりやすい。
しかし、普通そういうログは確認後に残すものだから Travis 回して確認 → ログ書いて commit, push はめんどくさい。

まあ、普通に考えたら 2 かな?というわけで、空コミットするお仕事に戻ります。

2014/08/15

rails-froutes という gem をリリースした

Summary

Rails の routes を peco りたかったんで rails-froutes という gem を作りました。
Github: pinzolo/rails-froutes
RubyGems.org: rails-froutes

How?

インストールして、rake routes FILL_NAME=yesと呼び出すと、従来は
    blog_posts GET    /blogs/:blog_id/posts(.:format)          posts#index
               POST   /blogs/:blog_id/posts(.:format)          posts#create
 new_blog_post GET    /blogs/:blog_id/posts/new(.:format)      posts#new
edit_blog_post GET    /blogs/:blog_id/posts/:id/edit(.:format) posts#edit
     blog_post GET    /blogs/:blog_id/posts/:id(.:format)      posts#show
               PUT    /blogs/:blog_id/posts/:id(.:format)      posts#update
               DELETE /blogs/:blog_id/posts/:id(.:format)      posts#destroy
         blogs GET    /blogs(.:format)                         blogs#index
               POST   /blogs(.:format)                         blogs#create
      new_blog GET    /blogs/new(.:format)                     blogs#new
     edit_blog GET    /blogs/:id/edit(.:format)                blogs#edit
          blog GET    /blogs/:id(.:format)                     blogs#show
               PUT    /blogs/:id(.:format)                     blogs#update
               DELETE /blogs/:id(.:format)                     blogs#destroy
こうだった rake routes の結果が、
    blog_posts GET    /blogs/:blog_id/posts(.:format)          posts#index
    blog_posts POST   /blogs/:blog_id/posts(.:format)          posts#create
 new_blog_post GET    /blogs/:blog_id/posts/new(.:format)      posts#new
edit_blog_post GET    /blogs/:blog_id/posts/:id/edit(.:format) posts#edit
     blog_post GET    /blogs/:blog_id/posts/:id(.:format)      posts#show
     blog_post PUT    /blogs/:blog_id/posts/:id(.:format)      posts#update
     blog_post DELETE /blogs/:blog_id/posts/:id(.:format)      posts#destroy
         blogs GET    /blogs(.:format)                         blogs#index
         blogs POST   /blogs(.:format)                         blogs#create
      new_blog GET    /blogs/new(.:format)                     blogs#new
     edit_blog GET    /blogs/:id/edit(.:format)                blogs#edit
          blog GET    /blogs/:id(.:format)                     blogs#show
          blog PUT    /blogs/:id(.:format)                     blogs#update
          blog DELETE /blogs/:id(.:format)                     blogs#destroy
こうなります。

Why?

ほら routes.rb みれば大体わかるとはいえ、ちょっと規模が大きくなると **_path, とか **_url を頭の中でごにょごにょするのはタルいわけです。
% rake routes | peco | awk '{print $1}' | pbcopy
とかできたら便利じゃないですかね?
でも、通常の rake routes だと名前があったりなかったりで欲しいものが取れないので、こんな gem を作りました。
まあ現実だと rake routes はもっさりなので
% rake routes FILL_NAME=yes > .routes
ってあらかじめしておいて、
% cat .routes | peco | awk '{print $1}' | pbcopy
ってところですかね。
私はこれを proutes として .zshrc に登録しました。
guard で routes.rb 監視して、更新したら吐き出すようにしておくのもいいかもしれません。
そこまで routes.rb を頻繁にいじるかどうかはわかりませんが。

2014-08-16 追記:
改行が入るのは使いづらいのでコマンドを改良した。
% cat .routes | peco | awk '{print $1}' | tr -d '\n' | pbcopy

おまけ

こんなふうに出力するオプションって rake routes にないの?って思ってコード読んでたら、こんなの発見した。 いや〜知らんかった。

2014/08/11

Windowsで解凍できるZIPファイルをRubyで作成する

Windowsで解凍できるZIPファイルを Ruby で作る必要があったのでメモ。
利用したのは rubyzip/rubyzip の v1.1.6
概ね、rubyzip/README.md at master · rubyzip/rubyzip の通りなんだけど、Windows で解凍できるようにするには Shift_JIS に変換したパスで格納してあげる必要がある。
実際に使用する際には、外部から Shift_JIS か UTF8 かを選べるようにするのがいいかもね。

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 用の設定をコピーしてくることになりがち。 こんな感じに。

ここまではいい。

問題は、ここからちょいと修正を入れてしまうことにある。
ちょっと文言をいじってしまうと ActiveModel のデフォルトの文言を上書きするということになる。
これを複数プラグインでやってしまった場合、さてあなたのプラグインではどんなエラーが表示されるだろう?
これらの辞書ファイルはマージされるので、ロード順や入れてあるプラグインの状態により変わってしまい想定できなくなる。
文言をテストで使用していたりしたら、テストが失敗してしまう。
それを避けるためにも、先のエントリで書いたようなテクニックを利用して、自分のプラグインの ActiveModel が使用するセクションを独立させてあげよう。
こんな感じに。(my_plugin 部分にはあなたのプラグインの一意な識別子を指定しましょう。)

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

2014/08/01

ActiveSupport::Concern の included と ClassMethods の順序

前置き

最初に書いておきます、Rails3.2系の記事です。
Rails4だと ActiveModel::Model を使うだろうから、サンプルコードはずいぶん変わると思います。

ActiveModel を利用したモデルで独自の i18n のセクションを利用したい

まあとある事情で、通常 activemodel.errors.messages.xxx な i18n のキーを my_model.errors.messages.xxx とかにしたかった。
そんな場合は i18n_scope をオーバーライドしてやるんだけど、全モデルクラスに書くのは嫌なので、インクルードするだけの共通モジュールを書くことに。

最初にこんなのを書いた

しかし、これではうまくいかない。

問題点

ActiveSupport::ConcernClassMethods モジュールを反映させてから included のブロックを実行するので、再度デフォルトで上書きしてしまう。

解決策

こんな風に alias_method_chain を使うなどして extend ActiveModel::Translation の後にオーバーライドしてやればいい。