« 02.16 春が来たと思ったら雪が来た | ココ | 02.23 足の感覚がなくなった »

2009年2月20日

acts_as_taggable_on_steroids X will_paginate  このエントリーを含むはてなブックマーク 

今は、もう、動かない、そのこーまんどー。というか、もうwill_paginateはプラグインではないらしいんですが。ええ、つまり script/plugin install ... が。

gem版ではなくプラグインでのwill_paginateなので古いんですが、こいつとacts_as_taggable_on_steroidsを組み合わせて使おうとすると、Model.tag_listで止まる…。という現象に会社でRubyの復習をしてたときに遭遇。

vendor/plugins/will_paginate/lib/will_paginate/finder.rb:92:in `method_missing_without_paginate'
vendor/plugins/will_paginate/lib/will_paginate/finder.rb:93:in `method_missing'
vendor/plugins/acts_as_taggable_on_steroids/lib/acts_as_taggable.rb:155:in `tag_list'
app/views/b/list.rhtml:7:in `_run_erb_47app47views47b47list46rhtml'
app/views/b/list.rhtml:5:in `each'
app/views/b/list.rhtml:5:in `_run_erb_47app47views47b47list46rhtml'
/usr/lib/ruby/gems/1.8/gems/actionpack-2.1.0/lib/action_view/base.rb:338:in `send'
/usr/lib/ruby/gems/1.8/gems/actionpack-2.1.0/lib/action_view/base.rb:338:in `execute'
/usr/lib/ruby/gems/1.8/gems/actionpack-2.1.0/lib/action_view/template_handlers/compilable.rb:29:in `send'
/usr/lib/ruby/gems/1.8/gems/actionpack-2.1.0/lib/action_view/template_handlers/compilable.rb:29:in `render'

script/consoleで確認してみたら、tag_listを保存(Model.save)するときにもエラーが起こる。

SystemStackError (stack level too deep):
/vendor/plugins/will_paginate/lib/will_paginate/finder.rb:93:in `method_missing_without_paginate'
/vendor/plugins/will_paginate/lib/will_paginate/finder.rb:93:in `method_missing'
/vendor/plugins/acts_as_taggable_on_steroids/lib/acts_as_taggable.rb:173:in `save_tags'
/usr/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/callbacks.rb:173:in `send'
/usr/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/callbacks.rb:173:in `evaluate_method'

うーん。意味が分からん。なんでmethod_missing_without_paginateなんや。method_missing_without_paginateなんて関数宣言されてないし…とか探してたら、Railsじゃ関数のオーバーライドをするときにalias_method_chain(ref. The Kumagmatic Kumagrammers)を使うとwith_xxxとwithout_xxxが作られるのか。method_missing_without_paginateはVB.net風に言えばMyBase.method_missing()でmethod_missing_with_paginateはMyClass.method_missing()か。まあ自分で処理できんかったらMyBaseで処理するわな、確かに。

/vendor/plugins/will_paginate/lib/will_paginate/finder.rb

      def method_missing_with_paginate(method, *args, &block)
        # did somebody tried to paginate? if not, let them be
        unless method.to_s.index('paginate') == 0
          return method_missing_without_paginate(method, *args, &block)
        end
      ...(続く)

とりあえず、method_missing_without_paginateを呼び出す前のところにデバッグコード入れたら、mapがないってたくさんmap map map 吐き出したから。なんでやろーとさらに悩み続けて、ActiveRecordは普通に中身吐かせたら[]で出てくるのにArrayじゃないんやな、なんと紛らわしい。

/vendor/plugins/acts_as_taggable_on_steroids/lib/acts_as_taggable.rb

      def tag_list
        return @tag_list if @tag_list

        if self.class.caching_tag_list? and !(cached_value = send(self.class.cached_tag_list_column_name)).nil?
          @tag_list = TagList.from(cached_value)
        else
          tags2 = self.tags.find(:all)
          @tag_list = TagList.new(*tags2.map(&:name))

        end
      end

      def save_tags
        return unless @tag_list

        tags2 = self.tags.find(:all)
        new_tag_names = @tag_list - tags2.map(&:name)
        old_tags = tags2.reject { |tag| @tag_list.include?(tag.name) }

        self.class.transaction do
          if old_tags.any?
            taggings.find(:all, :conditions => ["tag_id IN (?)", old_tags.map(&:id)]).each(&:destroy)
            taggings.reset
          end

          new_tag_names.each do |new_tag_name|
            tags << Tag.find_or_create_with_like_by_name(new_tag_name)
          end
        end

        true
      end

というわけで、明示的にtag.find(:all)として配列にしてやった。…にしても、なんでpaginateと組み合わせるとうまくいかんのやろ、暗黙の型変換(?)がうまく機能しない様子。いわゆるプラグイン同士の相性というか、食べ合わせの問題? Railsみたいに人気になると、こういうこともあるのね。Rubyの設計思想も何か影響あるのかしらん。

By ただ at 19:19 カテゴリー ; PinMarch Samples , プログラミング単語帳 , プログラミングとか

« 02.16 春が来たと思ったら雪が来た | 02月の記事 | 02.23 足の感覚がなくなった »




トラックバック

このエントリーのトラックバックURL:
http://pinmarch.sakura.ne.jp/mt/mt-tb.cgi/1373