icon 《基础 Ruby on Rails》的示例程序asagao与Rails2.2相适应

分页

上一章中首页成功地显示出来。

单元测试通过了吗?

> rake test:units
(省略)
/usr/lib/ruby/gems/1.8/gems/activesupport-2.2.2/lib/active_support/dependencies.rb:428:in
 `load_missing_constant': Expected /home/kuroda/hgrepos/books/kiso_rails/cd-rom/chapter9/
app/helpers/mobile/blog_entries_helper.rb to define Mobile::BlogEntriesHelper (LoadError)
(省略)

唔,没有通过。看一下问题 app/helpers/mobile/blog_entries_helper.rb ,显示如下。

module Mobile::BlogsHelper
end

在这里必须向读者道歉。CD-ROM 附带的源代码中有错误。请做如下修改。实在抱歉。

module Mobile::BlogEntriesHelper
end

这样,单元测试通过了。

接下来进行功能测试。

> rake test:functionals
(省略)
92 tests, 235 assertions, 4 failures, 13 errors
(省略)

啊,失败了。

大致看一下错误信息,分页出现了问题。

分页在 rails 2.0 以后,就从框架主体分离开来成为了插件。就那样的话行不通。

rails 2.0 刚发布的时候,被告知要安装 classic_pagination 插件,试着安装一下的话……

> ruby script/plugin install svn://errtheblog.com/svn/plugins/classic_pagination
svn: 主机 'errtheblog.com' 无法连接: Connection refused

出现了这样的拒绝信息。好像已经不提供了。

那么决定使用 mislav-will_paginate 代替(性能上优于 classic_pagination)。

> gem sources -a http://gems.github.com
http://gems.github.com added to sources
> sudo gem install mislav-will_paginate
Successfully installed mislav-will_paginate-2.3.6
1 gem installed
Installing ri documentation for mislav-will_paginate-2.3.6...
Installing RDoc documentation for mislav-will_paginate-2.3.6...

接受读者的建议,在安装步骤中追加了下一项。

> gem sources -a http://gems.github.com

mislav-will_paginate 插件,并不是标准的 gem 存储,而是通过 GitHub 发布的。

config/environment.rb 后添加如下语句。

  config.gem 'mislav-will_paginate', :lib => 'will_paginate'

添加位置在

Rails::Initializer.run do |config|
  ...
end

的内部。

那么,让我们一个个地进行解决吧。首先从 main 控制台开始。。

> ruby test/functional/main_controller_test.rb

这里出现了大量的警告和错误信息。首先想想办法解决下面这个错误吧。

NameError: uninitialized constant MainController::Paginator

原来的变成下面这样:

(省略)
  # 我们的活动
  def activities
    page = (params[:page] || 1).to_i
    @activities, count = 
      Article.current_articles('activities', ARTICLES_PER_PAGE, page)
    @activities_pages =
      Paginator.new(self, count, ARTICLES_PER_PAGE, page)
    @number_of_members = Member.count
  end
  
  # 新闻
  def news
    page = (params[:page] || 1).to_i
    @news, count = 
      Article.current_articles('news', ARTICLES_PER_PAGE, page)
    @news_pages =
      Paginator.new(self, count, ARTICLES_PER_PAGE, page)
  end
(省略)

将这个进行重写:

(省略)
  # 我们的活动
  def activities
    @activities =
      Article.current_articles('activities').paginate(:page => params[:page], :per_page => ARTICLES_PER_PAGE)
    @number_of_members = Member.count
  end
  
  # 新闻
  def news
    @news =
      Article.current_articles('news').paginate(:page => params[:page], :per_page => ARTICLES_PER_PAGE)
  end
(省略)

接下来,重写模板 activities.rhtmlnews.rhtml
则变成下面这样:

(省略)
<% if @activities_pages.page_count > 1 -%>
<div class="pagination">
  <%= my_pagination_links @activities_pages, :window_size => 9 %>
</div>
<% end -%>
(省略)

重写activities.rhtml

(省略)
<%= will_paginate @activities, :previous_label => '上一步', :next_label => '下一步', :inner_window => 2 %>
(省略)

重写news.rhtml

(省略)
<%= will_paginate @news, :previous_label => '上一步', :next_label => '下一步', :inner_window => 2 %>
(省略)

我们做的插件 pagination_links 和插件 mislav-will_paginate 中,因为到第1页的连接的写法不同,所以重写测试。

打开 test/functional/main_controller_test.rb ,将所有的 a[href=/main/news] 换成 a[href=/main/news?page=1]

这样 main_controller_test.rb 就通过了。

但是,像下面这样的警告却大量显示。

DEPRECATION WARNING: truncate takes an option hash instead of separate length and omission arguments.

从 Rails2.2 开始, truncate 方法的参数的获取方式就发生了改变。

Rails 2.1 以前,还是 truncate(text, length, omission) ,Rails 2.2 以后就变成了 truncate(text, *args) ,字符串的长度由 :length 选项表示。

      <%= my_format(truncate(a.body, 20)) %></li>

将这个做如下修改。

      <%= my_format(truncate(a.body, :length => 20)) %></li>

再次进行所有的功能测试。

> rake test:functionals
(省略)
92 tests, 278 assertions, 4 failures, 8 errors
(省略)

错误从 13 减至 8 。

真是辛苦。今天就到这儿吧。

(2008/12/17)