ホーム DoRuby Rails2.3アプリのRuby1.8⇒1.9移行に伴って得た知見

Rails2.3アプリのRuby1.8⇒1.9移行に伴って得た知見

この記事はアピリッツの技術ブログ「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 に移行中です。

その中でまた問題と解決方法が見つかり次第、本記事に追記していこうと思います。

記事を共有

最近人気な記事