partial_counterは1から始まるのが好き

Railsにはいろいろな規約があって、その一つにpartial_counterという変数がある。(詳しくは以前の日記render :partialカウンター、オブジェクトもどうぞ)

  • Rails 2.0.2までは0からカウントされ、
  • Rails 2.1で1からカウントされるようになり、
  • そして最近リリースされたRails 2.1.1で、また0からカウントされる仕様に戻った...。

つまり、Rails 2.1の1から始まりはバグだった、ということなのかな?
ほとんどビューの中でしか利用しないpartial_counterは、行番号を表示するために利用することが多く、1から始まるのが結構気に入っていたのに。
...ということで、Rails 2.1仕様の1からカウントされるpartial_counterに修正してみることに。

diff(差分の確認)

  • まずはRails2.1と2.1.1の差分を確認してみた。(あらかじめソースコードを一生懸命読んで、partial_template.rbの部分が怪しいと予想)
$ diff -U 5 /Library/Ruby/Gems/1.8/gems/actionpack-2.1.0/lib/action_view/partial_template.rb /Library/Ruby/Gems/1.8/gems/actionpack- 2.1.1/lib/action_view/partial_template.rb 
 --- /Library/Ruby/Gems/1.8/gems/actionpack-2.1.0/lib/action_view/partial_template.rb	2008-06-20 22:43:21.000000000 +0900
 +++ /Library/Ruby/Gems/1.8/gems/actionpack-2.1.1/lib/action_view/partial_template.rb	2008-09-09 09:24:16.000000000 +0900
 @@ -20,14 +20,14 @@
          @handler.render(self)
        end
      end
     
      def render_member(object)
 -      @locals[@counter_name] += 1
        @locals[:object] = @locals[@variable_name] = object
       
        template = render_template
 +      @locals[@counter_name] += 1
        @locals.delete(@variable_name)
        @locals.delete(:object)
       
        template
      end
  • 違いは、@locals[@counter_name] += 1の位置のみ。
    • Rails 2.1ではtemplate = render_templateより前に実行されていたが、
    • Rails 2.1.1ではtemplate = render_templateの後で実行されるように変更されている。

ヘルパーに登録

  • そこでrender_memberメソッドの部分だけ都合のいいように変更して、application_helper.rbに設定してみた。
# Methods added to this helper will be available to all templates in the application.
module ApplicationHelper
end

module ActionView #:nodoc:
 class PartialTemplate < Template #:nodoc:
   # partial_counterを1からカウントする(1, 2, 3...)
   def render_member(object)
     @locals[@counter_name] += 1
     @locals[:object] = @locals[@variable_name] = object
     
     template = render_template
     @locals.delete(@variable_name)
     @locals.delete(:object)
     
     template
   end
 end
end

確認

<h1>Listing todos</h1>

<table>
  <tr>
    <th>No.</th>
    <th>Body</th>
    <th>Due</th>
    <th>Done</th>
  </tr>

  <%= render :partial => @todos %>
</table>

<br />

<%= link_to 'New todo', new_todo_path %>
  <tr>
    <td><%=h todo_counter %></td>
    <td><%=h todo.body %></td>
    <td><%=h todo.due %></td>
    <td><%=h todo.done %></td>
    <td><%= link_to 'Show', todo %></td>
    <td><%= link_to 'Edit', edit_todo_path(todo) %></td>
    <td><%= link_to 'Destroy', todo, :confirm => 'Are you sure?', :method => :delete %></td>
  </tr>


これで、1からカウントされるようになったようだ!


ちなみに、Rails 2.1.1をインストールしても今のところ上記の件以外は、自分の環境では問題なく稼働している感じ。

今後は?

今後はどうなるのだろうと思い、Rails 2.2を目指している最新のRailsの状態を見てみると...

render_partial_collectionメソッドの178行目辺りのなのだろうか?今後も0から始まるような気がする。それなら変な修正はやめて、カウンターが0から始まる前提で修正しておいた方が良いかもしれない...。