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 の後にオーバーライドしてやればいい。

2014/07/22

Railsにてポリモーフィック関連のサンプルコード

Rails のポリモーフィック関連って便利ですよね。
でも、関連の貼り方までは結構サンプルコードが転がっているんですが、データ保存部分まで含めたものがあまりないような気がしたので、どうするのがいいかなと悩みつつ書いてみた。

has_oneの場合

has_one のサンプルとして、備考のモデルで作ってみた。
コメントは結構複数の場合があるけど、備考はたいてい 1 つしか持たないだろう。 1つしかオブジェクトを持たないので、note 属性で値を直接やりとりしたかったのでこんな風に。
Notable を include すればもう備考書き放題。

has_manyの場合

こんどは定番のタグをサンプルにしてみた。 関連テーブルをポリモーフィック関連にするわけですな。

雑感

* xxx_typexxx_id は Rails に任せる。自分では処理しない。
* 関連を定義してくれる module を作っておくと後が便利だと思う。
* t.references :taggable, polymorphic: true とするサンプルが多いけど、null が入ることは設計上ありえないんだから null: false を付けておいたほうがいいと思う。
* save_note では保存のみ実行しているけど、note_store.note が nil の場合はデータサイズ的なことを考えると note_store.destroy としてもいいと思う。(集約されるテーブルなので) まあサンプルなのでシンプルにした。

2014/07/15

Redmine 2.5.0 からプラグインでの文言上書きが復活しています

Redmine 2.3, 2.4 のころはプラグインで登録した locales よりも、本体の locales が load_path での優先度が高く、tail -f pinzo.log: Redmineのプラグインで既存の文言を上書きする みたいなことをしないと、文言を上書きできませんでした。
しかし、Redmine 2.5 からプラグインが読み込まれると、本体の locales よりも優先度が高くなるように load_path に登録されるため、特に何もせずに上書きされるようになっています。
コレが関連のチケット → Patch #12753: Update config.i18n.load_path for plugin-supplied locales - Redmine
I18n.load_path でなく Rails.application.config.i18n.load_path に追加すると。なるほど

Vagrant で Bitnami Redmine の環境を作る

検証環境として Vagrant 上に bitnami redmine を構築したのでメモ。

Vagrant

% vagrant box add centos65 https://github.com/2creatives/vagrant-centos/releases/download/v6.5.3/centos65-x86_64-20140116.box
% vagrant init centos65
これで Vagrantfile が作成されたので少し編集。
起動して最新状態にしておく
% vagrant up
% vagrant ssh
$ sudo yum check-update
$ sudo yum update

Bitnami のインストール

$ sudo yum install wget
# 公式サイトでは 32bit が Recommended されているが、こっちでないと動かない
$ wget https://bitnami.com/redirect/to/38030/bitnami-redmine-2.5.2-0-linux-x64-installer.run
$ chmod 775 bitnami-redmine-2.5.2-0-linux-x64-installer.run
$ sudo ./bitnami-redmine-2.5.2-0-linux-x64-installer.run
ウィザード形式でインストールが完了するが、最初に英語を選ばないと、表示が怪しい

Redmine を自動起動に

$ sudo cp /opt/redmine-2.5.2-0/ctlscript.sh /etc/init.d/bitnami-redmine
$ sudo vi /etc/init.d/bitnami-redmine
こちらを参考に少しスクリプトを編集
$ chkconfig --add bitnami-redmine # ついでに起動しておく $ sudo sh /etc/init.d/bitnami-redmine

アクセス

いちいち ip 打つのはめんどくさいので hosts に 192.168.33.10 vm を追加して、http://vm/redmine にアクセス。
無事表示された。
こんな感じ。さすが All in one、かなりフルで入る。

2014/07/14

RxTstudy 11th で発表してきました

先日 7/12 に大阪で行われた RxTstudy 11th で一時間ほどセッションしてきました。
初の長時間セッションということで、資料作成時にどれぐらいの分量を書けばいいかわからず、時間が余った時のためにおまけネタも用意していたのですが、ちょうどいい感じで終われたので安心しました。
使わなかったおまけネタは今度どこかの LT ででも発表したいと思います。

スライドはこちら。 スライドだけではニュアンスが伝わらない部分が結構あると思いますが、@akahane92 さんが録画してくださってていて、そのうちアップされると思いますので、そちらを御覧ください。
その他のスライドや全体の感想などは @akipiiさんの第11回RxTstudy勉強会「Redmine Plugin 活用最前線」の感想~今後の課題はRedmineのエコシステムの創造 #RxTStudy: プログラマの思索にまとまっています。

以下、今回の私的な感想やフォローです。
  • 今回のRxTstudy はセッションは2つと少なめですが、どちらも一時間の長めのセッションであり、パネルディスカッションもあったので結構ボリュームも有り、人によっては疲れたかもしれません。
  • プラグインを作り始めてまだ日の浅い私と違い、@haru_iidaさんの経験からくるお話が非常に勉強になりました。
  • いくつかで、Redmine 本体のテスト実行に2,3時間という話が出ていますが、こんな感じのビルドマトリクスを Travis-CI で走らせた場合、Travisの状況によっては二時間後ぐらいに全部終わった通知が来ることもあるということです。ローカルで rake ci する分には 10〜20分足らずで終わります。
  • 私が言及した Redmine とプラグインを取り囲むエコシステムの欠乏というのがひとつの大きな主題となって「価値のある発表ができたな」という自己満足感があったw
  • プラグインを利用したRedmineの情報集約能力は非常に高いと思うのでお勧めですよ
  • Redmine環境の構築、プラグインの導入の敷居はまだまだ高いらしい。プラグイン作りまくったり自分で環境立ちあげたりしているとその辺りの感覚が薄れてしまうので、それらを考慮した開発をこれからも心がけたい
ほんまこれ

2014/07/11

tmuxとvimとpbcopy

peco/peco が便利で色々と設定をしていたら、vim のヤンク→ペーストが出来ない場合があることに気づいた。
どうも、tmux から呼び出した vim でクリップボード連携をしていると動かないらしい。
あと pbcopy も動かなかった。
調べてtmux上で起動したvimでヤンクする時にクリップボードを使う - takanamitoのブログを参考に解決したのでメモ。
# reattach-to-user-namespace をインストール
% brew install reattach-to-user-namespace

# .tmux.conf に設定追加
% echo 'set-option -g default-command "reattach-to-user-namespace -l zsh"' >> ~/.tmux.conf

# Brewfile にも忘れずに追加
% echo 'install reattach-to-user-namespace' >> ~/src/github.com/pinzolo/env/Brewfile
これで tmux からの vim や gvim でクリップボードが使えるし、pbcopy も正常に動きます。

2014/07/09

Redmine2.5.2のプラグインアップデート確認機能が使えない

前回のエントリで、せっかく新機能として追加されたプラグインアップデートの確認機能ですが、VPS 上の Redmine では失敗する。
ブラウザの開発ツールを使えば原因は一目瞭然。
アクセス先の URL がベタ書きなので、Redmine を HTTPS 運用していても http://www.redmine.org/plugins/check_updates にアクセスしてしまい、セキュリティ上ブロックされてしまう。
上の画像からそもそもリクエストを発行すらしていないことがわかる。
じゃあ、https にアクセスすればいいんじゃね?と app/views/admin/plugins.html.erb を修正してみる。
// 修正前
dataType: "jsonp",
url: "http://www.redmine.org/plugins/check_updates",
data: <%= raw_json plugin_data_for_updates(@plugins) %>,
// 修正後
dataType: "jsonp",
url: "//www.redmine.org/plugins/check_updates",
data: <%= raw_json plugin_data_for_updates(@plugins) %>,
そうすると今度は別のエラーが発生する。
リクエストは正常に発行されているが、500エラーが返ってくる。
それも当然で、https://www.redmine.org というのはどうも SVN の WebDAV アクセスで使用されているっぽい。
ちなみに直接アクセスしてみるとこんな画面になる。

これどうすんだろ?Redmine を HTTPS 運用しているのは結構多いと思うんだが、このままではこの機能を利用することはできない。
SVN のリポジトリの URL を今更変えるというのも大変だろうし。
別の URL で API を提供するのがいいんじゃねーかな?http://api.redmine.org と https://api.redmine.org みたいな感じで。

[追記]
ちなみにエラーになるのは Google chrome と Firefox で Opera と Safari は正常に機能しました。
IEでは初回に警告がでるものの「すべてのコンテンツを表示」をクリックすれば実行可能。

Redmine 2.5.2 へアップデート

さくらVPSの Redmine を 2.5.2 にアップデート。
毎回同じことやっているので、スクリプト化。
一発成功。
余程の大きく破壊的なバージョンアップでない限りコレで行けるはず。

せっかくなので、新機能のプラグインバージョンチェックを試してみると...
むむむむ、調査せねば

2014/07/04

ActiveRecord の ! つきメソッドについて

ActiveRecord の更新系メソッドには、!つきのものとそうでないものがあって、一般的には例外を発生させるかどうかの違いという認識だと思う。
しかし!が付いているからといって例外を発生させるメソッドとは限らない。
属性値を変更するだけで、!がつくと同時に保存も実行するというパターンも存在する。 なので、「decrement で減らしているけど、万が一負数になってしまった場合、例外を発生させてトランザクションを失敗させる」場合(バリデーションでやれというのは置いといて)、@user.decrement!(:count) ではなくて @user.decrement(:count).save! と書かなければならない。

あと、 becomesbecomes! という STI(単一テーブル継承)用のメソッドもあるが、これはちょっと別枠ですね。
ちなみに becomes!becomes + type カラムの変更となっていて、変換後に保存するときに便利なのかな。あんまり STI を使ったことないけど。

2014/07/03

prettyprint が有効にできた

tail -f pinzo.log: ブログデザイン変えたで有効にならねーと嘆いていた Google code prettify だが、どうやら指定するスクリプトが違っていたようだ。
<!-- 誤 -->
<script src='http://google-code-prettify.googlecode.com/svn/trunk/src/prettify.js' type='text/javascript'></script>
<!-- 正 -->
<script src='https://google-code-prettify.googlecode.com/svn/loader/run_prettify.js' type='text/javascript'></script>
間違っていたスクリプトはモジュールだけで実行はしてくれないっぽいな。

screen から tmux に乗り換えた

tmux の存在はずっと知っていたけど、screen 自体ヘビーユーザーでもないので特に乗換のメリットが見いだせずそのまま使い続けていた。
しかし、なぜか唐突に GVim 派だけどコンソールでたまに使う Vim でも綺麗な色で使いたい!と思い、調べてみると別に特に設定などはいらなさそう。
ならなぜ俺の vim はこんなにも貧相な色なんだ!!と調べるとどうやら screen が対応していないらしい。
自前でビルドするのもめんどくさいので、tmux に乗り換えてみた。
もともと screen 自体を対した設定にしていないので、.tmux.conf も少し調べたらかけた。
しかし、これがなかなか有効にならない。C-t が効かずC-b が無効になっていない。
どうやら tmux は exit で全部終了してから、再度起動しても設定ファイルを再読み込みしてくれるわけではないらしい。
設定ファイルを再度読み込む方法はあるんだろうが、調べるのがめんどくさかったので killall tmux して再度立ち上げたらちゃんと反映された。
とりあえず今の .tmux.conf はこんな感じ。
# utf-8
set-window-option -g utf8 on
set-option -g status-utf8 on

# prefix: C-b -> C-t
unbind C-b
set-option -g prefix C-t

# ignore all bells
set-option -g bell-action none

# highlight status line on window activity
set-window-option -g monitor-activity on

# use vi keybinds
set-option -g mode-keys vi

# reduce escape key delay
set-option -sg escape-time 1

# reload ~/.tmux.conf
bind r source-file ~/.tmux.conf \; display "Reloaded!"

# show last window
bind C-t last-window

# enter copy mode
unbind Escape
bind Escape copy-mode

# enable rbenv local
set-environment -gu RBENV_VERSION

# default status color
set-option -g status-fg black
set-option -g status-bg white

# current window's status color
set-window-option -g window-status-current-fg blue
set-window-option -g window-status-current-bg white
これでカラフルな vim がコンソールでも使えるようになった。
そして、homebrew のビールも表示されるようになった。

2014/06/27

gem 開発が少し便利になる .pryrc

gem の動きを pry で確認するのはよくあることで、
pry(main)> $LOAD_PATH.unshift './lib'
pry(main)> require 'my_gem'
みたいなのを毎度やっていた。
誰かの gem の挙動を確認したいなーというだけならまだいいけど、自分で開発している時に何度もやるのはめんどくさい。
そんな時に役に立つのが .pryrc こんなのを書いておいた。
カレントディレクトリに my_gem.gemspec ファイルがあれば gem だと判断し、 lib/my_gem.rb があれば自動的に require してくれる。

2014/06/25

Gemfile.local を使う

例えばこんな Gemfile を書いていて push したら、CI でpry-byebug は Ruby 2.0 以降でないと動かないと怒られた。
ローカルでは、2.1.2だから気が付かなかった。

そこでこんなふうに修正して開発してた。
そしたらある日 binding.pry を消し忘れて push してしまいテストが終わらなかった。

CI が当たり前となった現在、こういう Gemfile は無駄が多いんじゃなかろうか。
pry-byebug などのデバッグツールはテストの時に必須なのではないので、CI時には無視したい。
おそらくそのための機能が group なんだろうけど、環境に応じて bundle install のオプションをあれこれしなければいけないのはちょっとめんどくさい。できれば bundle install と path などの使い慣れたオプションだけで完結させたい。

で、話変わって Redmine には Gemfile.local という仕組みがあって、Redmine の実行と直接関係ない gem を記述する方法が用意されている。
Redmineのインストール — Redmine Guide 日本語訳 によると、Redmine本体は使用しないgem(例: mongrel, fcgi)もロードしたい場合のための仕組みらしい。
せっかくなので、Redmine 以外の開発でも導入してみよう。
こんな感じで Gemfile と Gemfile.local を作り、.gitignore に Gemfile.local を指定する。
CI時に不要な gem がダウンロードも読み込みもされることはないし、ローカルの開発ではデバッグできる。
bundle install する時に余計なオプションもいらない。
大体、デバッグツールなどは使い慣れたものが個人個人にあって、誰かの設定に左右されるべきものではない。

ただし、当然デメリットもあってコレを許すということは個人個人の開発環境で差異が出ることを意味する。
なので、余計なトラブルが起こる可能性も多少あがる。
まあ、それは使う使わないの選択の問題であって、仕組みとしてはあったほうが便利だと思う。

2014/06/19

MacVim の Ruby 連携

MacVim で Ruby との連携がいつの間にか取れなくなって、結構前から todesking/ruby_hl_lvar.vim が動かなくなっていた。
どうも Release MacVim-KaoriYa 20140501 · splhack/macvim から動かなくなったようだ。
Ruby 2.1 をインストールして RUBY_DLL を設定しろとあるが、ここらへんを参考にしても動かない。
そもそも、libruby.2.1.dylib が存在していない。
dylib を作るためには、--enable-shared オプションを付けてビルドするという情報を見つけ、Ruby2.1.2を入れなおした。
CONFIGURE_OPTS="--enable-shared --with-readline-dir=`brew --prefix readline` --with-openssl-dir=`brew --prefix openssl`" rbenv install 2.1.2
しかしそれでも libruby.2.1.dylib は作成されない。
ひたすらぐぐってこの一連のやりとりを見つけたので、プレリリースでもこの際仕方ないとRelease MacVim-KaoriYa 20140514 · splhack/macvimを入れたらあっさり連携した。
ローカル変数にも色がついた。
次の本リリースまではこれでいこう。

2014/06/18

redmine_reminderz

pinzolo/redmine_reminderz という Redmine のプラグインを作った。
Redmineには締め切りの近いチケットを通知する redmine:send_reminders というRakeタスクがあるが、今のプロジェクトでは進捗率80%以上のチケットはレビュー待ちなので担当者にリマインダーとして送りたくないらしい。
多分 Redmine の運用方針を変えればカバーできる話だが、Redmineをそんなにガシガシと使いこなしているわけでもないし、プロジェクト的にそこまでの余裕もない。
というわけで、進捗率でフィルタできるオプションを追加したタスクをプラグインとして作成した。
タスク名を redmine:send_reminders から redmine:send_reminderz に変更するだけ(最後のsをz)
既存のオプションはそのまま使えて、進捗率を >, >=, <, <= でフィルタするオプションが指定できる。

開発30分、目視確認30分の突貫作業だったので、まだテストもないし、設計もよろしくない。
既存のタスクに独自オプションによる処理を差し込む方法が思いつかず丸々コピーしてしまった。
redmineから始まるタスク名もあまり良くないなとちょっと後悔している。そのうち別名でも用意する。
とまあ、だいぶ中途半端な出来だけど、せっかくなので公開しておく。
テスト、オプションの充実、締め切り通知以外のリマインダーの追加などできる事は結構あると思うので、ゆっくり育てます。

2014/06/13

Redmine のプラグインを RSpec3 でテスト出来ない

pinzolo/redmine_persist_wfmt を RSpec3 に対応しようとしてみたが実行すら出来なかった。
/Users/pinzolo/projects/redmine/persist_wfmt/redmine-2.5.1/vendor/bundle/ruby/2.1.0/gems/rspec-support-3.0.0/lib/rspec/support/version_checker.rb:28:in `raise_too_low_error': You are using capybara 2.1.0. RSpec requires version >= 2.2.0. 
(RSpec::Support::LibraryVersionTooLowError)
        from /Users/pinzolo/projects/redmine/persist_wfmt/redmine-2.5.1/vendor/bundle/ruby/2.1.0/gems/rspec-support-3.0.0/lib/rspec/support/version_checker.rb:18:in `check_version!'
        from /Users/pinzolo/projects/redmine/persist_wfmt/redmine-2.5.1/vendor/bundle/ruby/2.1.0/gems/rspec-rails-3.0.1/lib/rspec/rails/vendor/capybara.rb:13:in `'
        from /Users/pinzolo/projects/redmine/persist_wfmt/redmine-2.5.1/vendor/bundle/ruby/2.1.0/gems/activesupport-3.2.17/lib/active_support/dependencies.rb:251:in `require'
        from /Users/pinzolo/projects/redmine/persist_wfmt/redmine-2.5.1/vendor/bundle/ruby/2.1.0/gems/activesupport-3.2.17/lib/active_support/dependencies.rb:251:in `block in require'
        from /Users/pinzolo/projects/redmine/persist_wfmt/redmine-2.5.1/vendor/bundle/ruby/2.1.0/gems/activesupport-3.2.17/lib/active_support/dependencies.rb:236:in `load_dependency'
        from /Users/pinzolo/projects/redmine/persist_wfmt/redmine-2.5.1/vendor/bundle/ruby/2.1.0/gems/activesupport-3.2.17/lib/active_support/dependencies.rb:251:in `require'
        .... and more
Redmine 本体の Gemfile で gem "capybara", "~> 2.1.0" なのだが、RSpec3 で Capybara を使用するには 2.2.0 以上を要求される。
このエラーは実行時でなく事前チェックで投げられているようで、 Capybara をプラグインのテストで使用していなくても出る。
さすがに本体のバージョンを無視するわけにはいかないので、当分は gem "rspec", "~> 2.14.0" で行こうと思う。
というか、やっぱりこういうのを避けるためには ActiveSupport::TestCase で書いたほうがいいんだろうな。

RSpec3ではもう-cfsオプションは許してくれない

2.1.2 とか Rails 4.1 での CI 設定を手持ちの gem に一気に済ませてビルドしたら一気にコケた。
tekido #20
formap #36

こんな感じでコケる。
/home/travis/.rvm/rubies/ruby-2.1.2/bin/ruby -I/home/travis/.rvm/gems/ruby-2.1.2/gems/rspec-core-3.0.1/lib:/home/travis/.rvm/gems/ruby-2.1.2/gems/rspec-support-3.0.0/lib -S /home/travis/.rvm/gems/ruby-2.1.2/gems/rspec-core-3.0.1/exe/rspec spec/formup/attr_def_spec.rb spec/formup/source_spec.rb spec/formup_boolean_cast_spec.rb spec/formup_included_spec.rb spec/formup_initialize_spec.rb spec/formup_load_spec.rb spec/formup_params_for_spec.rb spec/formup_source_called_spec.rb spec/formup_validation_spec.rb -cfs
/home/travis/.rvm/gems/ruby-2.1.2/gems/rspec-core-3.0.1/lib/rspec/core/formatters.rb:167:in `find_formatter': Formatter 's' unknown - maybe you meant 'documentation' or 'progress'?. (ArgumentError)
 from /home/travis/.rvm/gems/ruby-2.1.2/gems/rspec-core-3.0.1/lib/rspec/core/formatters.rb:126:in `add'
 from /home/travis/.rvm/gems/ruby-2.1.2/gems/rspec-core-3.0.1/lib/rspec/core/configuration.rb:624:in `add_formatter'
 from /home/travis/.rvm/gems/ruby-2.1.2/gems/rspec-core-3.0.1/lib/rspec/core/configuration_options.rb:106:in `block in load_formatters_into'
 from /home/travis/.rvm/gems/ruby-2.1.2/gems/rspec-core-3.0.1/lib/rspec/core/configuration_options.rb:106:in `each'
 from /home/travis/.rvm/gems/ruby-2.1.2/gems/rspec-core-3.0.1/lib/rspec/core/configuration_options.rb:106:in `load_formatters_into'
 from /home/travis/.rvm/gems/ruby-2.1.2/gems/rspec-core-3.0.1/lib/rspec/core/configuration_options.rb:24:in `configure'
 from /home/travis/.rvm/gems/ruby-2.1.2/gems/rspec-core-3.0.1/lib/rspec/core/runner.rb:96:in `setup'
 from /home/travis/.rvm/gems/ruby-2.1.2/gems/rspec-core-3.0.1/lib/rspec/core/runner.rb:85:in `run'
 from /home/travis/.rvm/gems/ruby-2.1.2/gems/rspec-core-3.0.1/lib/rspec/core/runner.rb:70:in `run'
 from /home/travis/.rvm/gems/ruby-2.1.2/gems/rspec-core-3.0.1/lib/rspec/core/runner.rb:38:in `invoke'
 from /home/travis/.rvm/gems/ruby-2.1.2/gems/rspec-core-3.0.1/exe/rspec:4:in `
'
原因はここ。 要するに「s なんてフォーマット知らないよ」ということ。
bundle exec rspec --helpしても確かにそんなものはない。ていうか、2.14の頃からすでにない。
ググったらたくさん出てくるので、かつてはあったんだろう。
2.14のころは許容していたのか、厳密ではなかったのかしらないが3からは厳密になったということかな。
さあ、あなたの Rakefile や .rspec も見なおしてみましょう。

2014/06/12

zsh環境の正常化とpecoとzshが連携出来ないお話

ghqを使ったローカルリポジトリの統一的・効率的な管理について - delirious thoughts をやってみようと思い、ghq と gem-src は無事導入できた。 最近は golang 製の percol である lestrrat/peco というものがあるらしく、全く使っていない pip を使うよりいいなとやってみたが zsh の連携が出来ない。
function peco-src() {
    local selected_dir=$(ghq list --full-path | peco --query "$LBUFFER")
    if [ -n "$selected_dir" ]; then
        BUFFER="cd ${selected_dir}"
        zle accept-line
    fi
    zle clear-screen
}
zle -N peco-src
bindkey '^S' peco-src
こんなのを.zshrcに書いたが、Ctrl-S で起動しないし、直接 peco-src とやってディレクトリを選択するとエラーになる。
peco-src:zle:4: widgets can only be called when ZLE is active
peco-src:zle:6: widgets can only be called when ZLE is active
あれこれいじったり調べていると、どうも自分の zsh の環境が少しおかしいことに気づく。
% echo $module_path
/usr/lib/zsh/5.0.2/zsh
% zsh --version
zsh 5.0.5 (x86_64-apple-darwin13.0.0)
明らかにおかしい。どうやら、実行しているシェルは Mac に元から入っていた zsh のようだ。
おそらく、購入時に環境設定した時には chsh -s /bin/zsh したんだろう。
さっそく、homebrew の zsh に切り替える。
% sudo sh -c "echo /usr/local/bin/zsh" >> /etc/shells
% chsh -s /usr/local/bin/zsh
しかし、下記のエラーが出た。
/Users/pinzolo/.zshenv:1: command not found: rbenv
/Users/pinzolo/.zshenv:2: command not found: pyenv
compinit:183: module `zsh/parameter' has no such feature: `p:dis_patchars': autoload cancelled
compinit:183: module `zsh/parameter' has no such feature: `p:patchars': autoload cancelled
rbenv と pyenv のエラーは .zshenv の先頭に export PATH="/usr/local/bin:$PATH" を追加したら消えた。
compinit のエラーは zsh を再インストールしたら消えた。
% brew uninstall zsh
% brew install zsh --enable-etcdir
しかし、それでも peco-src は動かない。
/usr/local/Cellar/zsh/5.0.5/libzle.so はあるし、.zshrc 内では zle は動いていると思われる。
実行時にエラーが出るんだが、どうしてなんだろうか?
調べても同様の状況の人が出てこない。どうしたものか

2014/06/10

rails-render_hooks という gem を作った

Redmine のプラグインなんかを作っていると、アクションの処理が終了してレンダリングされる前にちょっと手を入れたくなる。
実際そういう需要はそれなりにあるようで、'rails before_render' とかで検索するとチョロチョロ出てくる。
しかし、Rails3.2〜Rails4.1で動くぐらいにメンテされている gem がない。
  • shell/rails3_before_render
    Rails4 で動かないし、Rails4で動くように修正されたプルリクエストも放置
  • nilesh/before_render
    上記から fork して Rails4 で動くけど、逆に Rails3.2 で動かない
  • codepodu/rails3_before_render
    上記のプルリクエスト元なのでどっちでも動くけどRails4.1だとテスト落ちる。そもそも Travisこけてるけど放置。プルリクエスト用だから gem になってない
というわけで、自分で作った ついでに、before だけでなく、after と around も足しておいた。使うかどうかは知らないけど。

2014/06/06

git-2.0.0をサーバにインストール

% cd /opt/src
% wget https://www.kernel.org/pub/software/scm/git/git-2.0.0.tar.gz
% tar xf git-2.0.0.tar.gz
% cd git-2.0.0
% ./configure --prefix=/opt/git/git-2.0.0 --with-openssl --with-curl
% make
% make install
% /opt/git/git-2.0.0/bin/git --version
git version 2.0.0
% ln -sfn /opt/git/git-2.0.0/bin/* /usr/bin % git --version
git version 2.0.0
ln -sfnでシンボリックリンクが上書きできることを初めて知ったのでメモ。

2014/05/29

drone.io を試してみた

普段は Travis CI で CI を回してるんだけど、drone.io もよいという話なのでちょっと試してみた。

作業の流れ

右上の New Project を選んで
リポジトリを選択。Github の他に BitBucket と Google code にも対応している。
ビルドしたいリポジトリを選んで
言語を選択。Ruby はまだ beta らしい。
ビルドスクリプトを設定する。シェルスクリプトを書けばいい感じかな?
基本形ははじめから入力されているので、このまま行ける。
更に周辺の設定を追加して Save → Build Now
ビルドが開始して、
結果が表示される。
こんな割と簡素なメールが飛んでくる。
README.md などに貼るバッジも用意されている。

気になったとこ・所感

Rubyのバージョンは現時点では3つしかなく、Ruby2.1.0以降はまだない。
それから、言語のバージョンがひとつしか設定できないので、Travisのようなマルチバージョンでのテストができないっぽい。どっかから設定できるのだろうか?
ビルドの速度は速い気がする。golangだからか?
ビルドスクリプトはわりと何でも出来そうなので、シェルスクリプト書けるならかなり柔軟性がありそうだ。
設定ファイルをリポジトリに置かないのは余計なものを置かなくていいし、ブラウザ上で完結するので便利だけど、皆で知見を共有しづらいのじゃないかな?

言語のバージョンと環境変数のマトリクスが Travis の一番の魅力なので、それが簡単に出来ないならばあまり切り替える魅力は今のところないかなぁ
ほんとに軽く触っただけなので、こうすればいいよとかあったら是非教えて下さい。

2014/05/23

[解決編]UbuntuをアップグレードしたらRedmineでRMagick関連が動かなくなっていた

先日の tail -f pinzo.log: [未解決]UbuntuをアップグレードしたらRedmineでRMagick関連が動かなくなっていた の解決編。

原因調査

まず、何を基準にエラーとしているかを調べる。
該当のURLは /admin/info なので、redmine/app/views/admin/info.html.erb を見るが、それらしい箇所はない。
view になければ controller だろうということで redmine/app/controllers/admin_controller.rb を見る。
あった、単に Magick という定数が定義されているかどうかで判別されているみたいだ。

なぜ定義されていないのか?

RMagick は redmine/lib/redmine.rb で明示的に require されていて、エラーを握りつぶされていた。これでは、ログにはでてこないわけだ。
というわけで、状況再現のためにこちらも require してみる。
% bundle exec rails c production
irb(main):001:0> require 'RMagick'
LoadError: libjpeg.so.62: cannot open shared object file: No such file or directory - /var/lib/rails/redmine-2.5.1/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.1/vendor/bundle/ruby/2.1.0/gems/activesupport-3.2.17/lib/active_support/dependencies.rb:251:in `require' from /var/lib/rails/redmine-2.5.1/vendor/bundle/ruby/2.1.0/gems/activesupport-3.2.17/lib/active_support/dependencies.rb:251:in `block in require' from /var/lib/rails/redmine-2.5.1/vendor/bundle/ruby/2.1.0/gems/activesupport-3.2.17/lib/active_support/dependencies.rb:236:in `load_dependency' from /var/lib/rails/redmine-2.5.1/vendor/bundle/ruby/2.1.0/gems/activesupport-3.2.17/lib/active_support/dependencies.rb:251:in `require' from /var/lib/rails/redmine-2.5.1/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.1/vendor/bundle/ruby/2.1.0/gems/activesupport-3.2.17/lib/active_support/dependencies.rb:251:in `require' from /var/lib/rails/redmine-2.5.1/vendor/bundle/ruby/2.1.0/gems/activesupport-3.2.17/lib/active_support/dependencies.rb:251:in `block in require' from /var/lib/rails/redmine-2.5.1/vendor/bundle/ruby/2.1.0/gems/activesupport-3.2.17/lib/active_support/dependencies.rb:236:in `load_dependency' from /var/lib/rails/redmine-2.5.1/vendor/bundle/ruby/2.1.0/gems/activesupport-3.2.17/lib/active_support/dependencies.rb:251:in `require' from (irb):1 from /var/lib/rails/redmine-2.5.1/vendor/bundle/ruby/2.1.0/gems/railties-3.2.17/lib/rails/commands/console.rb:47:in `start' from /var/lib/rails/redmine-2.5.1/vendor/bundle/ruby/2.1.0/gems/railties-3.2.17/lib/rails/commands/console.rb:8:in `start' from /var/lib/rails/redmine-2.5.1/vendor/bundle/ruby/2.1.0/gems/railties-3.2.17/lib/rails/commands.rb:41:in `<top (required)>' from script/rails:6:in `require' from script/rails:6:in `<main>'
libjpeg.so.62 がないのが原因のようだ。

解決方法

libjpeg.so.62 は libjpeg62 をインストールすればいいらしい。
aptitude install libjpeg62
あとは、passenger を再起動したら・・・・

直ったーーーーーーー

2014/05/22

ブログデザイン変えた

このブログのデザインを変えたので作業メモ。
すっきりしたデザインになってよろしい。

独自スタイル

headタグに下記を埋め込んで終了。せっかくなので少し修正した。
Github Pages 便利。
<link href='http://pinzolo.github.io/blog/style.css' rel='stylesheet' type='text/css'/>

ソーシャルボタン

以前は blogger のオプションを使っていたんだけど、はてなブックマークなどは自分で埋め込まなきゃいけないので、忍者おまとめボタンに移行した。便利だなコレ
最初は何度更新しても表示されなかったが、Chrome の AddBlock Plus にひっかかってたからだった。
ホワイトリストドメインに mkt-sys.jp を追加したらあっさり表示された。
しかし、とういことは AddBlock Plus 使っている人には見えないということか、しばらく様子を見る。

コードハイライト

本格的にハイライトしたい場合は Gist を使うので、手軽な Code pretty を使用してる。
これまではブログパーツだったけど、新デザインだとエリアが表示されてしまうので、直接埋め込んだ
<!-- ヘッダに -->
<link href='http://google-code-prettify.googlecode.com/svn/trunk/src/prettify.css' rel='stylesheet' type='text/css'/>

<!-- bodyの閉じタグ直前に -->
<script src='http://google-code-prettify.googlecode.com/svn/trunk/src/prettify.js' type='text/javascript'></script>
しかし、ハイライトされていないっぽい。原因不明。→2014-07-03: 有効にできた

AdSense

一応埋め込んで放置していたんだけど、1月に申請して未だに申請が通っていない。
俺の何かがおかしいんだと思うけど、よくわからん。
でなぜかさっき承認のメールが届いた。ウィジェット置いていたつもりが置けていなかったからのようだな。
金になるようなブログじゃないけど一応置いてみる。

2014/05/21

Ubuntu12.04のJavaをアップデート

さくらVPSのUbuntu12.04のJavaを更新したので作業メモ。
% add-apt-repository ppa:webupd8team/java
% aptitude update
% aptitude install oracle-java7-installer
% aptitude install oracle-java8-installer
変更する。
% update-alternatives --config java
There are 3 choices for the alternative java (providing /usr/bin/java). Selection Path Priority Status ------------------------------------------------------------ * 0 /usr/lib/jvm/java-8-oracle/jre/bin/java 65 auto mode 1 /usr/lib/jvm/java-6-sun/jre/bin/java 63 manual mode 2 /usr/lib/jvm/java-7-oracle/jre/bin/java 64 manual mode 3 /usr/lib/jvm/java-8-oracle/jre/bin/java 65 manual mode
ん?Java8に自動的になってる?
% java -version
java version "1.8.0_05" Java(TM) SE Runtime Environment (build 1.8.0_05-b13) Java HotSpot(TM) 64-Bit Server VM (build 25.5-b02, mixed mode)
なってた

2014/05/18

RedmineでMarkdownに切り替えやすくするプラグインを作った

tail -f pinzo.log: Redmine がついに Markdown をサポートしたようだ で書いたように、Redmine が 2.5.0 から試験的に Markdown をサポートしたけど、過去の Textile で書いたもろもろが崩れてしまうので、気軽に乗り換えられない。
でも、やっぱり Markdown で書きたい。主流だし。
というわけで redmine_persist_wfmt というプラグインを作った。
これで少しは気軽に Markdown に切り替えられるですよ。

インストール

README.md にある通り。
$ bundle exec rake pwfmt:persist_all FORMAT=textile RAILS_ENV=production で既存のドキュメントを Textile として保存する。もちろん Markdown として保存することもできる。

イメージ

こんな風に Textile で書かれたドキュメントがあったとする。

プラグインをインストール後、Markdownを使うように変更する。

それでも Textile として変換されて表示されます。

もちろん Markdown として保存すれば

Markdown として変換されて表示されます。

作成・編集時にフォーマットを選択できるので、Textile から Markdown に直すこともできます。(もちろん逆も)

機能とメリット

  • 作成時に指定したフォーマットでずっと表示できる
  • 作成・編集時にフォーマットを指定できる(どちらかしかしらないメンバーがいても大丈夫)
  • 編集時にフォーマットを切り替えられる(統一も順次対応できる)

対応箇所

  • Redmineのウェルカムテキスト
  • プロジェクトの概要
  • チケットの概要と履歴
  • Wiki
  • 文書
  • フォーラムの本文とコメント
  • ニュース
基本的に Wiki 記法で書ける場所は全て対応したつもり

注意事項

  • ツールバーの動作は切り替わらない。Redmineの設定に従う
  • プレビューも未対応。Redmineの設定に従う → v1.1.0 で対応しました。
  • プラグインとかで追加された場所は、フォーマットを選択するドロップダウンはでるかもしれないけど書式は保存されないと思う

プレビューぐらいは対応したいけど、その前にテスト書いてリファクタリングをしたい。
似ているようで微妙に違うソースがたくさんなので、もう少し綺麗になるはず。

2014/05/16

[未解決]UbuntuをアップグレードしたらRedmineでRMagick関連が動かなくなっていた

さくらのVPSのUbuntu10.04を12.04に上げたらいつの間にかRedmineのRMagic関連機能が使えなくなっていた。
% convert
convert: error while loading shared libraries: libjpeg.so.62: cannot open shared object file: No such file or directory
convert が失敗するのが原因のようだ。
10.04の時はリポジトリのバージョンが古くソースからインストールしたので今回も最新版をソースからインストールした。
% wget http://www.imagemagick.org/download/ImageMagick-6.8.9-1.tar.gz
% tar xf ImageMagick-6.8.9-1.tar.gz
% cd ImageMagick-6.8.9-1
% ./configure --enable-lzw=yes --prefix=/opt/ImageMagick/ImageMagick-6.8.9-1
% make
% make install
% /opt/ImageMagick/ImageMagick-6.8.9-1/bin/convert --version
Version: ImageMagick 6.8.9-1 Q16 x86_64 2014-05-16 http://www.imagemagick.org Copyright: Copyright (C) 1999-2014 ImageMagick Studio LLC Features: DPC OpenMP Delegates: bzlib freetype jng jpeg lcms png tiff x xml zlib
インストールが成功したので、既存と置き換える。
% mv /usr/local/bin/animate{,.bak}
% mv /usr/local/bin/compare{,.bak}
% mv /usr/local/bin/composite{,.bak}
% mv /usr/local/bin/conjure{,.bak}
% mv /usr/local/bin/convert{,.bak}
% mv /usr/local/bin/display{,.bak}
% mv /usr/local/bin/identify{,.bak}
% mv /usr/local/bin/import{,.bak}
% mv /usr/local/bin/Magick-config{,.bak}
% mv /usr/local/bin/Magick++-config{,.bak}
% mv /usr/local/bin/MagickCore-config{,.bak}
% mv /usr/local/bin/MagickWand-config{,.bak}
% mv /usr/local/bin/mogrify{,.bak}
% mv /usr/local/bin/montage{,.bak}
% mv /usr/local/bin/stream{,.bak}
% mv /usr/local/bin/Wand-config{,.bak}

% ln -s /opt/ImageMagick/ImageMagick-6.8.9-1/bin/* /usr/bin
% convert --version
Version: ImageMagick 6.8.9-1 Q16 x86_64 2014-05-16 http://www.imagemagick.org Copyright: Copyright (C) 1999-2014 ImageMagick Studio LLC Features: DPC OpenMP Delegates: bzlib freetype jng jpeg lcms png tiff x xml zlib
RMagick を再インストール。
bundle exec gem uninstallでエラーは出るけどちゃんと削除はされるらしい。
% cd /var/lib/rails/redmine
% bundle exec gem uninstall rmagick
Successfully uninstalled rmagick-2.13.2 ERROR: While executing gem ... (NoMethodError) undefined method `delete' for #
% bundle install % touch tmp/restart.txt
その結果がこれである。
なんでや・・・

git1.9.3をインストール

バージョン1.7はさすがに古いなと思ったので、さくらVPSのUbuntu12.04にgitの最新版をインストールした。
% wget https://www.kernel.org/pub/software/scm/git/git-1.9.3.tar.gz
早速エラー。https対応をしていなかった。
% echo 'ca-certificate = /etc/ssl/certs/ca-certificates.crt' >> /etc/wgetrc
% wget https://www.kernel.org/pub/software/scm/git/git-1.9.3.tar.gz
% ./configure --prefix=/opt/git/git-1.9.3 --with-openssl --with-curl
% make
/bin/sh: 1: msgfmt: not found
とエラーになった。どうやらgettextが必要らしい。
% aptitude install gettext
% make
% make install
% /opt/git/git-1.9.3/bin/git --version
git version 1.9.3
インストールが成功したので、既存と置き換える。
% aptitude remove git-core
% ln -s /opt/git/git-1.9.3/bin/* /usr/bin
% git --version
git version 1.9.3
お疲れ様でした。

2014/05/12

Ruby 2.1.2 と 2.0.0-p481 をインストール

Hash#reject の挙動が修正され、readline 6.3 に対応した新しい ruby がリリースされたのでインストールした。
# readline のバージョンを最新に
% brew switch readline 6.3.5
# Ruby 2.0.0-p481 をインストール
% CONFIGURE_OPTS="--with-readline-dir=`brew --prefix readline` --with-openssl-dir=`brew --prefix openssl` --with-gcc=clang" rbenv install 2.0.0-p481
% rbenv global 2.0.0-p481 && rbenv rehash
% gem install pry bundler
# Ruby 2.0.0-p481 をインストール
% CONFIGURE_OPTS="--with-readline-dir=`brew --prefix readline` --with-openssl-dir=`brew --prefix openssl` --with-gcc=clang" rbenv install 2.1.2
% rbenv global 2.1.2 && rbenv rehash
% gem install pry bundler

2014/05/11

さくらの VPS を Ubuntu 10.04 から 12.04 にアップグレード

Ubuntu 14.04 も出たけど、とりあえずさくらの VPS を Ubuntu 10.04 から 12.04 にアップグレードした。
基本的には さくらのVPSでubuntu12.04にアップデートしたら、resolv.confの中身が空っぽになった件 | 流浪のプログラマのブログ を参考に行って、resolv.conf も同じように対応したら、名前解決も無事できた。

しかし、Redmine が動かない。
どうやら、/usr/bin/ruby 等の Ruby 関連のシンボリックリンクが Ubuntu 12.04 デフォルトの 1.8.7 に上書きされたのが原因っぽい。
tail -f pinzo.log: Rubyのアップデートがちゃんとできていなくて、Redmineをアップデートできなかった で作業した ruby2.0.0-p451 の本体は当然ながらしっかり残っていたので、再度シンボリックリンクを貼って apache を再起動したら Redmine も正常稼働した。

2014/04/28

ほとんど誰の役にも立たない Rails 4.1 での変更点

Book.where(category: 'comics')
こんなコードを書いた場合、Rails 4.0 まではこんなログが出力されていました。
Book Load (0.1ms)  SELECT "books".* FROM "books" WHERE "books"."category" = 'comics'
でも Rails 4.1 ではこんなログが出力されます。
Book Load (0.1ms)  SELECT "books".* FROM "books"  WHERE "books"."category" = 'comics'
WHERE の前の半角スペースが 1 つ増えてます。
おかげで rails-flog のテストが Rails 4.1 でコケる。
さて、直そう

rbenv で ruby がインストールできなくなった

おもむろに最新パッチレベルとそろそろruby2.1.1を入れようと思って、

CONFIGURE_OPTS="--with-readline-dir=`brew --prefix readline` --with-openssl-dir=`brew --prefix openssl` --with-gcc=clang" rbenv install 2.0.0-p451
を叩いたらエラーでインストールできなかった。
エラーログを見てみると下記のようなエラーメッセージが出ていたので、どうやら readline 関連でエラーが出ているらしい。
readline.c:1886:26: error: use of undeclared identifier 'Function'
    rl_pre_input_hook = (Function *)readline_pre_input_hook;
                         ^
readline.c:1886:36: error: expected expression
    rl_pre_input_hook = (Function *)readline_pre_input_hook;

調べてみると、どうやら readline が 6.3 になって rbenv でインストールしようとしたらエラーになるということらしい。
参考:MacでRuby 2.x.xがインストールできないバグ (homebrew + rbenv) - Qiita
readline を以前のバージョンに戻せばインストールできるとのことなので、

pinzolo@ileach % brew info readline
readline: stable 6.3.3 (bottled) http://tiswww.case.edu/php/chet/readline/rltop.html This formula is keg-only. OS X provides the BSD libedit library, which shadows libreadline. In order to prevent conflicts when programs look for libreadline we are defaulting this GNU Readline installation to keg-only. /usr/local/Cellar/readline/6.2.2 (30 files, 1.6M) /usr/local/Cellar/readline/6.2.4 (30 files, 1.6M) /usr/local/Cellar/readline/6.3.3 (40 files, 2.1M) * Poured from bottle From: https://github.com/Homebrew/homebrew/commits/master/Library/Formula/readline.rb
6.2.4 が入っていることを確認して、
pinzolo@ileach % brew switch readline 6.2.4
Cleaning /usr/local/Cellar/readline/6.2.2 Cleaning /usr/local/Cellar/readline/6.2.4 Cleaning /usr/local/Cellar/readline/6.3.3 Opt link created for /usr/local/Cellar/readline/6.2.4
readline を切り替えて再度インストールしたら無事インストールできた。

2014/04/13

Redmine がついに Markdown をサポートしたようだ

Redmine.org の issue を眺めていると Feature #15520: Markdown formatting - Redmine が上に上がっていた。
この要望は定期的にあがるよなーと思って読んでいると、なんととうとうサポートしたとのこと。 2.5.0 - Redmineを見ると、確かに 2.5.0 で追加されてる。
Github, Gist, Qiita, はてなブログ, wri.pe などなど Markdown はエンジニアのメモ記法のデファクトスタンダードになっているので、これは嬉しいニュース。待ち望んでいた人も多いのでは。

設定

確かに experimental となっていますが、Markdown が選択できるようになってます。
プロジェクト単位ではなく、Redmine全体での選択になるけど、もともと書式選択が全体なのは従来の仕様なのでこれはしかたない。

試してみた

早速こんな markdown で wiki を書いてみた。 これがこんなふうになる。
内部では Redcarpet 2.3 を使用しているので当然ながら GFM なシンタックスハイライトまでサポートされているのは嬉しい。

周辺サポート

experimental ながらしっかり周辺もサポートされてて、markdown を選んだ場合には wiki 用のツールバーも markdown 用になっており、各ボタンを押すと markdown に対応した書式を追加してくれる。
ちなみに下記の場所で Markdown が使えているのを確認済み。ほぼ漏れ無く対応されている感じ。
  • Wiki
  • 文書
  • プロジェクトの概要
  • チケットの説明
  • チケットの履歴の注記

残念なところも

ちなみに事前に textile でこんな文書を書いておいて、設定変更後に確認してみるとこうなる。
残念ながら書式は保存されないようです。
textile に設定を戻すと、markdown で書いた文書も textile で解釈された見れたもんじゃない文書になってしまう。
つまり現時点で markdown を使おうと思えば、過去の資産を全て捨てる、もしくは書き換えるしかないということになりますね。
残念だけど正式サポートの頃にはなんとかなるんだろうか?書いた時の書式を保存するとか。

markdown のサポートは現時点で experimental なのでこれから進化していくと思うとドキドキですね。

2014/04/12

Rubyのアップデートがちゃんとできていなくて、Redmineをアップデートできなかった

さくらのVPSで使用している Redmine を最新にしようと思い立った。

% cd work
% wget http://www.redmine.org/releases/redmine-2.5.1.tar.gz
% tar xf redmine-2.5.1.tar.gz
% mv redmine-2.5.1 /etc/lib/rails
% cd /etc/lib/rails/redmine-2.5.1
% cp ../redmine/config/database.yml config/
% cp ../redmine/config/configuration.yml config/
% bundle install --path vendor/bundle
% bundle exec rake generate_secret_token

ここまで順調に来たが、ここでエラー。

Could not find rake-10.1.1 in any of the sources
なぜか、bundler から bundler で今しがたインストールしたはずの gem が参照できないらしい。
調べてみると、どうやら bundler が実行時に参照するのは vendor/bundle/ruby/2.0.0 以下、しかしインストール時にインストールしていたのは vendor/bundle/ruby/1.9.1 以下というちぐはぐな状態になっていた。

思い当たることは、ruby を 2.0.0 にアップデートしたこと。
「今の Redmine をインストールした → ruby 2.0.0 をインストール → 今回」なので今までの Redmine は問題なく動いていたんだろうな
しかも ruby 2.0.0 をインストールした時、手順を間違えて ruby 1.9.3 の実行ファイルを正しく更新できていなかったようだ。
つまり、gem は ruby 1.9.3 の頃のものが動いていて bundler によるインストールは 1.9.1 以下に配置するが、実行時は ruby 2.0.0 で動いているので 2.0.0 以下を参照しようとしていたということだな。

というわけなので、rubyの最新版からちゃんとインストールし直すことにした。

% wget http://ftp.ruby-lang.org/pub/ruby/2.0/ruby-2.0.0-p451.tar.gz
% tar xf ruby-2.0.0-p451.tar.gz
% cd ruby-2.0.0-p451
% ./configure --prefix=/usr/local/ruby-2.0.0-p451
% make
% make install
% rm /usr/bin/erb
% rm /usr/bin/gem
% rm /usr/bin/irb
% rm /usr/bin/rake
% rm /usr/bin/rdoc
% rm /usr/bin/ri
% rm /usr/bin/ruby
% rm /usr/bin/testrb
% ln -s /usr/local/ruby-2.0.0-p451/bin/* /usr/bin/

手順をミスった ruby-2.0.0-p353 が動かないように変更

% mv /usr/local/bin/erb{,.bak}
% mv /usr/local/bin/gem{,.bak}
% mv /usr/local/bin/irb{,.bak}
% mv /usr/local/bin/rake{,.bak}
% mv /usr/local/bin/rdoc{,.bak}
% mv /usr/local/bin/ri{,.bak}
% mv /usr/local/bin/ruby{,.bak}
% mv /usr/local/bin/testrb{,.bak}

bundler をインストール

% gem install bundler
% ln -s /usr/local/ruby-2.0.0-p451/bin/bundle /usr/bin/

passenger の最新をインストールして変更

% gem install passenger
% cd /usr/local/ruby-2.0.0-p451
% ./bin/passenger-install-apache2-module

# /etc/apache2/mods-available/passenger.load を下記に変更
LoadModule passenger_module /usr/local/ruby-2.0.0-p451/lib/ruby/gems/2.0.0/gems/passenger-4.0.41/buildout/apache2/mod_passenger.so

# /etc/apache2/mods-available/passenger.conf を下記に変更
PassengerRoot /usr/local/ruby-2.0.0-p451/lib/ruby/gems/2.0.0/gems/passenger-4.0.41
PassengerDefaultRuby /usr/bin/ruby

redmine-2.5.1 のインストールのやり直し

# 同じなので省略
% bundle install --path vendor/bundle
% bundle exec rake generate_secret_token
% bundle exec rake db:migrate RAILS_ENV=production
% bundle exec rake tmp:cache:clear RAILS_ENV=production
% bundle exec rake tmp:sessions:clear RAILS_ENV=production
% mkdir public/plugin_assets
% cd ../
% chown -R www-data:www-data redmine-2.5.1
% ln -s /var/lib/rails/redmine-2.5.1 /var/lib/rails/redmine
% service apache2 restart

ちゃんと表示されて一安心

2014/02/20

いろんな型の範囲に対する範囲内チェックメソッドのパフォーマンスチェックをやってみた

先日書いた pinzolo/tekido を開発していた時、どうも一部時間のかかる処理があった。
割合系の spec を確認するために、誤差1%で合格する spec を書いていたんだけど、各sampleで試行回数10000回だとどうしても、ちょくちょく誤差を超えてしまう。
試行回数を10倍の100000回で行うと安定して、誤差内でおさまるんだけどテストの実行に結構な時間がかかっていた。
調べてみると、どうやら日付の Range に対しての include マッチャが時間がかかっている。
実際はマッチャは関係なく、include? メソッドの実行が結構重い。
ドキュメントによると、cover? だと、両端の <=> 比較によるチェックを行うということなので置き換えてみるとずいぶんと高速になったので解決はした。

そんなこともあって、せっかくなのでいろんな Range に対して include?, member?, ===, cover? のパフォーマンスを測ってみた。

環境

MacBook Air 13-inch, Mid 2012
プロセッサ : 2GHz Intel Core i7
メモリ : 8GB 1600 MHz DDR3
ソフトウェア : OS X 10.9.1 (Mavericks)
Ruby : ruby 2.0.0p353

数値

ほとんど変わらないしそもそも高速なので何使おうがどうでもいいレベル。

文字列

相対的にみると圧倒的に cover? だけど、10000回で4秒ちょい、1回あたり0.4ミリ秒なら include? が使われててもまあ別にいいかなと思うレベル。(状況にもよるけど)

日付

さすがに差があり過ぎでコストも高いので無視できない(したくない)レベル。

ということで

範囲内チェックは一律 cover? を使うのが無難そうです。
RSpec にも cover マッチャがあるので単純に置き換えできます。
ちなみに、Windows7 32bit環境(MBAよりもスペックは低い)で試してみたら、数値と文字列は変わらなかったけど日付の上三つの処理時間は13秒ぐらいでした。
MBAよりも倍近く高速なのが興味深い。

2014/02/17

ランダムデータを作るときにちょっとは役に立つかもしれない gem を作った

先日お仕事で、ランダムなデモデータを作成する必要がありまして、そのとき感じたことをいくつか。

  • rand(0..2) と値ぐらいならいいが、 rand(0..2).zero? ? "foo" : "bar" みたいなコードを結構使うが、意味が汲み取りにくい。
  • 直接関係ない値はついつい固定値にしてしまいがち。おかげで、ほとんどのデータが同じメールアドレスとか誕生日とか。そして、あとで他の機能からそのデータを使うときに、またランダム生成する。
  • そもそもランダムなメールアドレスや日付などは一手間かかる。この手のデータ作成は一時的な使い捨てであることも多々あるので、ちょくちょく同じような処理を書くことになる。

というわけで、ランダムデータ作成用に gem を作ってみた。

pinzolo/tekido
tekido | RubyGems.org

適度にデータを作るようにということで tekido。
使い方は、 Tekido.integer とか Tekido.date とか Tekido.string でよく使うデータ型のランダムなデータを作成出来ます。
Tekido.percentTekido.emailTekido.birthday みたいなちょっといい感じににしてくれるメソッドもついてます。
Kernel.rand のように引数で色々作成するデータが変わるので詳しくは README.mdUSAGE_ja.md を見てください。

rand を多用するよりはメソッド名で意味を汲み取りやすいし、普段なら一手間かかるデータも一発で作れます。
これで、ランダムデータの作成も少しは楽になるかもしれません。

2014/02/09

自分流 Rails での区分値

Railsでの区分値の扱いについて考える - TIM Labs
ActiveHashを使ってRailsで区分値を扱う方法 - TIM Labs

このあたりを読んでの話。

自分の場合は、もっぱらDBに保存する派です。
まあ、理由はいくつかあって

  • SQLで使いやすい
    過去のしごとで「アプリケーションの機能を作る程ではないけどこういう統計情報がほしい」という依頼を受けることがわりとあって、その時に画面表示と同じ文言を JOIN だけで出せる。
    区分が増えるほど CASE が増えていく SQL は書くのも保守するのもしんどい。
    Rubyを通さないと区分と文言の定義を正しく取れないのは使いづらい。
  • 区分を増やしてもアプリケーションの更新が必要ない場合がある
    区分値というのはドロップダウンリスト、チェックボックスのリスト、ラジオボタンのリストなどで画面から選択させることがよくあります。
    そんな場合、マスタ管理の機能を組み込むなり、INSERT実行するなりでアプリケーションの更新なしで対応できます。
    プログラム内で区分値を特定して使用する場合に初めてアプリケーションの更新が必要というのは理にかなってると思う。
  • 区分の保存先は統一したい
    数が少ない区分はコードで定義したほうが使いやすいが、付随する情報が多い区分はDBに保存したくなりません?
    でも保存先が分散されるのは保守しづらいのでどこかに統一したい。そんな場合、大は小を兼ねるでDBを選択してます。
というメリットが大きいな、使いやすいなと感じています。

でもDBに保存した場合、二重管理というのは確かに頭を悩ませる問題ですね。

def self.male
  find(id: 1)
end
みたいなコードを過去には量産してしまったりしてました。
それはやっぱりよろしくないので、自分の場合はちょっとした gem を作って対応してます。

pinzolo/mastar という gem で、以下その紹介。

countries
id name code
1 日本 japan
2 アメリカ合衆国 usa

こんなテーブルに対して、

class Country
  include Mastar
  mastar.key :code
end

とすれば、Country.japanfind(1) の結果にアクセスできます。
code のような、一意なコードを扱う列を作らなければいけないですが、二重管理からは開放されるので個人的には重宝してますね。
機能だけ作って README.md 書くのがめんどくさくなって v0.9.0 としてひっそりリリースして放置してました。
せっかくなので Country クラスのオブジェクトに対して japan? で判別できるメソッドが生える機能を足して v1.0.0 としてリリースしました。 もし使えそうなら使ってみてください。

あ、あと view でドロップダウンリストのために f.select :country_id, Country.all.map { |c| [c.name, c.id] } やら f.collection_select :country_id, Country.all, :id, :name と書いていたのを f.select :country_id, Country.pairs と書けるようにもなります。地味に気に入ってます。

2014/01/26

Update rails-flog to v1.3.0

rails-flog(github, RubyGems.org) をバージョン 1.3.0 にあげた。

  • バージョン 1.2.0
    一時的にフォーマットを無効にする機能をパラメータとSQL個別に行えるようにした。
    どっちかのフォーマットだけ欲しい人も安心。
  • バージョン 1.3.0
    いくつかのフォーマットを行わないための条件を設定できるようにした。 「キャッシュされたクエリはフォーマットしたくない」とか「時間のかかるクエリだけ調査したいからフォーマットしてほしい」とか「キーが一つしかないパラメータをフォーマットすんなよ。行数増えて余計見づらいわ」みたいな人もニンマリ。
    ただし、デフォルトの挙動が変わっているので注意。

issue や pull request もお気軽にどうぞ