この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。
よしだです。
今回はRails2.3/Ruby1.8で動作する自社開発のオープンソースECパッケージ『エレコマ』を、Ruby1.9に移行するに伴って問題になった点と、その解決方法について紹介したいと思います。
■ 日本語メールが文字化けする
Ruby 1.9 になって、文字列オブジェクトが文字コードを持つようになりました。
このため Ruby 1.8 ⇒ 1.9 移行の際には、文字列が意図しない文字コードで解釈されてしまうのを防ぐ必要があります。
Rails 2 のメールシステムには TMail というライブラリが利用されています。
Ruby 1.9 でこの Tmail を利用すると、上記問題のため、メール処理部分で例外エラーが発生してしまいます。
これは config/initializers/tmail_19_patch.rb に下記のようなコードを設置することで解決できます。
# -*- coding: utf-8 -*-
# Ruby 1.9 + tmail-1.2.7 環境での
#「Encoding::CompatibilityError (incompatible encoding regexp match (ASCII-8BIT regexp with ISO-2022-JP string))」
# エラー対策。
# Rails の場合 config/initializers/tmail_19_patch.rb などに配置する。
#
module TMail19Jp
def self.encoding_handler(text)
raise unless block_given?
enc = text.encoding
text.force_encoding(Encoding::ASCII_8BIT)
result = yield
text.force_encoding(enc)
result
end
end
module TMail
class Encoder
alias :phrase_org :phrase
# 本文用のパッチ
def phrase(str)
TMail19Jp::encoding_handler(str) do
phrase_org(str)
end
end
end
# Subject欄用のパッチ
class Unquoter
class << self
alias :unquote_and_convert_to_org :unquote_and_convert_to
def unquote_and_convert_to(text, to_charset, from_charset = "iso-8859-1", preserve_underscores=false)
TMail19Jp::encoding_handler(text) do
unquote_and_convert_to_org(text, to_charset, from_charset, preserve_underscores)
end
end
end
end
end
# 本文用のパッチ
class StringOutput
alias :push_org :<<
def <<(str)
TMail19Jp::encoding_handler(str) do
push_org(str)
end
end
end
# From欄用のパッチ
module ActionMailer
module Quoting
alias :quote_address_if_necessary_org :quote_address_if_necessary
def quote_address_if_necessary(address, charset)
TMail19Jp::encoding_handler(address) do
quote_address_if_necessary_org(address, charset)
end
end
end
end
文字列を処理するまえに force_encoding(Encoding::ASCII_8BIT) で文字オブジェクトが持つ文字コードを変更しています。
こうすることで、意図しない文字コードで処理され、例外が発生するのを防いでいます。
参考: http://d.hatena.ne.jp/akishin999/20120220/1329731704
■ 半角カナ判別用の正規表現が動作しない
Ruby 1.9 で正規表現ライブラリが「鬼車」に変わったため、正規表現の一部表現がサポートされなくなっています。
エレコマでは、全角カナの判別にはもともと下記のような正規表現を利用していましたが、「鬼車」ではこのような文字コード単位での範囲指定を許可していないようです。
# 全角カナを判別するための正規表現 (for Ruby1.8)
KATAKANA_PATTERN = /^(?:\xE3\x82[\xA1-\xBF]|\xE3\x83[\x80-\xB6\xBC])*$/
これは moji という gem を利用すれば簡単に解決できます。
実際には下記のようなコードになります。
(※ここでは全角カナのほかに、マイナスなどの例外的な文字も含めるようにしています)
# 半角カナを判別するための正規表現 (for Ruby1.8)
KATAKANA_PATTERN = /^(#{Moji.zen_kata}|ー|-)*$/
また「鬼車」では /[\p{katakana}+/ のように書くことでカタカナの判別が可能です。
ただし、こちらは半角カナも含んでしまうため、今回の例では使用できませんでした。
■ PostgreSQL とうまく連携できない
エレコマでは DB として利用する PostgreSQL の gem に「postgres」を利用しています。
しかし、これは Ruby 1.9 では動作しないので、代替として「pg」をインストールします。
# gem uninstall postgres -v 0.7.9.2008.01.28
(古い gem をアンインストール)
# gem install pg --no-ri --no-rdoc
(Ruby 1.9 向けの新しい gem をインストール)
■ PostgreSQL が古くて pg がインストールできない
「pg」は PostgreSQL 8.3 以上が必要になります。
このためインストール済みの PostgreSQL のバージョンが低い場合はアップデートが必要になります。
【CentOSの場合】
すでに PostgreSQL が入ってしまっているなら、下記コマンドで古いパッケージをアンインストールします。
# yum uninstall postgresql-devel postgresql-server
その後 PostgreSQL を 8.4 (8.3以上であれば良い) にします。
# yum install postgresql84-devel postgresql84-server
■ さいごに
エレコマは現在 Ruby 1.9 に移行中です。
その中でまた問題と解決方法が見つかり次第、本記事に追記していこうと思います。