その他
    ホーム 技術発信 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 に移行中です。

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

    記事を共有