きにきじ」:今日の気になる記事をきまぐれにご紹介

Ruby1.8.7以降ではtruncateメソッドの仕様が変わったらしくエラーが起きる

Posted at 00:24 on August 27, 2010

Last updated at 22:54 on September 16, 2010

Category: Non-News, Note

Tags: , , , ,


基礎Ruby on Rails』を手にウェブアプリケーション "Morning Glory" を作成していたわけですが、第6章のデータを MySQL にインポートしたら以下のようなエラーが生じてしまいました。

1
2
NoMethodError in Main#index
undefined method `length' for #<Enumerable::Enumerator:0xb676c440>

問題の「Main#index」ってのは以下の RHTML ファイルです。どうやらこれの8行目にある truncate メソッドが引っかかっているご様子。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<% @side_bar_template_name = 'side_bar' -%>
<div id="whats_new">
<h2>What's New</h2>
<ul>
<% @new_articles.each do |a| -%>
  <li><%= link_to h(a.heading), :action => a.place,
            :anchor => "article_#{a.id}" %> 
      <%= truncate(h(a.body), 20) %></li>
<% end -%>
</ul>
</div>
<div id="main">
<% @top_articles.each do |a| %>
  <h2><%= h(a.heading) %></h2>
  <%= simple_format(h(a.body)) %>
<% end -%>
</div>

結論から言うと、これは Ruby のバージョンというか仕様に対してもともとのコードが噛み合ってないのが原因のようです。解決策は以下のとおり。

解決策はずばり、「\config\environment.rb の末尾1に修正コードを書き込む」です!2

そしてその修正コードはこちら。

1
2
3
4
5
6
7
8
9
10
11
module ActionView
  module Helpers
    module TextHelper
      def truncate(text, length = 30, truncate_string = "...")
        if text.nil? then return end
        l = length - truncate_string.chars.to_a.size
        (text.chars.to_a.size > length ? text.chars.to_a[0...l].join + truncate_string : text).to_s
      end
    end
  end
end

もともと Ruby には TextHelper#truncate メソッドが用意されているわけですが、それを定義し直すコードのようですね。

def truncate 以降を抽出した部分(以下のコード)を \app\helpers\application_helper.rb に加えても同じように動くみたいです。

1
2
3
4
5
def truncate(text, length = 30, truncate_string = "...")
  if text.nil? then return end
  l = length - truncate_string.chars.to_a.size
  (text.chars.to_a.size > length ? text.chars.to_a[0...l].join + truncate_string : text).to_s
end

注意点としては、これをやっちゃうと Ruby デフォルトの truncate メソッドが使えなくなるというのがあります。もしデフォルトの truncate メソッドが使えないと困るとかいう場合は他の方法を探す必要がありそうです。

基礎Ruby on Rails』に沿って Rails を勉強している方の内けっこうな方がこのエラーにやられると思われますので、このエントリが一助となれば幸いです。

▲上に戻る▲


よろしければ以下の関連(してそうな)記事もどうぞ!


Leave a Reply


Copyright © 2008-2012 鍵山琢実 (KAGIYAMA, Takumi). All rights reserved.

This site's design was checked by IE 6.0+, Firefox 3.5+, GChrome 2.0+, Safari 4.0+, Opera 10.0+, and Sleipnir 2.8+ (all for Windows).
And JavaScript is used for some details. I am so sorry if your browser is not supported.

正当なCSSです! 私はチーム・マイナス6%です

↓ Today's My Favorite Phrase ↓

「きさま──いったい何人の命をその傷のために吸い取った!?」
「おまえは今まで食ったパンの枚数をおぼえているのか?」

From: 荒木飛呂彦 『ジョジョの奇妙な冒険』第3巻 p. 149