如何在Ruby on Rails中为page_cache更改will_paginate中的链接格式?

时间:2010-01-11 23:25:43

标签: ruby-on-rails ruby caching will-paginate

我想将page_cache与will_paginate一起使用。

以下页面上有很多信息。

http://railsenvy.com/2007/2/28/rails-caching-tutorial#pagination http://railslab.newrelic.com/2009/02/05/episode-5-advanced-page-caching

我写了routes.rb看起来像:

map.connect '/products/page/:page', :controller => 'products', :action => 'index'

但是,url的链接不会更改为will_paginate helper中的'/ products / page /:page'。 他们仍然是'产品?页= 2'

如何在will_paginate中更改网址格式?

4 个答案:

答案 0 :(得分:6)

该路由是否在上面任何RESTful资源路由声明了吗?也就是说,您的路径文件应如下所示:

map.connnect '/products/page/:page', :controller => 'products', :action => 'index'
map.resources :products, :except => [:index]

如果您的路线看起来正确,您可以尝试使用will_paginate生成页面链接的方式进行猴子修补。它在WillPaginate::ViewHelpers#url_for(page)中这样做。这是一些相当复杂的逻辑,以处理一些棘手的边缘情况,但你可以编写一个新版本,首先尝试简单版本的product

# in lib/cache_paginated_projects.rb
WillPaginate::ViewHelpers.class_eval do
  old_url_for = method(:url_for)
  define_method(:url_for) do |page|
    if @template.params[:controller].to_s == 'products' && @template.params[:action].to_s == 'index'
      @template.url_for :page => page
    else
      old_url_for.bind(self).call(page)
    end
  end
end

答案 1 :(得分:1)

这对我有用

app/helpers/custom_link_renderer.rb

class CustomLinkRenderer < WillPaginate::LinkRenderer
  def page_link(page, text, attributes = {})
    @template.link_to text, "#{@template.url_for(@url_params)}/page/#{page}", attributes
  end
end

将此行添加到config/environment.rb文件

WillPaginate::ViewHelpers.pagination_options[:renderer] = 'CustomLinkRenderer'

答案 2 :(得分:1)

对当前答案的一点补充,我不得不花费数小时来弄明白。

如果您有一些更复杂的路线,例如在我的情况下包括过滤,确保首先出现“更高级别”路线(而不仅仅是它们在RESTful路线之上)否则will_paginate会选择第一个可用的,并以非常漂亮的方式将额外的参数添加到URL的末尾。

所以在我的情况下,我最终得到了这个:

map.connect "wallpapers/:filter/page/:page", :controller => "wallpapers", :action => "index", :requirements => {:page => /\d+/, :filter => /(popular|featured)/ }
map.connect "wallpapers/page/:page", :controller => "wallpapers", :action => "index", :requirements => {:page => /\d+/ }
map.resources :wallpapers

所以现在我得到了漂亮的网址: wallpapers / popular / page / 2 而不是 wallpapers / page / 2?filter = popular

答案 3 :(得分:0)

这样做:

map.products_with_pages "/products/page/:page", :controller => "products", :action => "index"

您甚至可以使用has_many ie:products has_many:items

map.resources :products do |product|
  map.items_with_pages "/products/:id/page/:page", :controller => "products", :action => "show"
end

然后您的控制器看起来像

def show
  product = Product.find(params[:id])
  @items = product.items.paginate :per_page => 5, :page => params[:page]
end

这会给你一个网址:http://domain.com/products/123/page/3其中123是产品ID,3是页面ID。你也可以使用永久链接,并将123 id更改为更友好的单词。