Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

In views of namespaced controllers, specifying params with a controller that begins with a '/' causes problems. #297

Open
sujoyg opened this Issue · 1 comment

2 participants

@sujoyg

Using rails 3.2.11 and will_paginate 3.0.4.

In the following, settings is a controller inside a namespace, and pages is a controller not inside any namespace.

config/routes.rb

...
namespace :admin do
  resources :settings
end
...
resources :pages
...

The following is a view template for settings#index, the controller inside a namespace:

views/admin/settings/index.html.haml

...
will_paginate @collection, params: {controller: '/pages', action: 'index'}
...

The reason controller is /pages and not simply pages is because if the latter were used, Rails url_for helper will assume that pages is a controller inside the admin namespace. Prefixing a controller name with a / is a convention that tells url_for that this is a top level controller.

Problem

The URL for the first will_paginate link is generated correctly, pointing to something like /pages?page=.... However, before subsequent links are generated the / prefix from the controller parameter is dropped and url_for fails, trying to generate a path for controller admin/pages, which does not exist.

Root cause

The url method in WillPaginate::ActionView ends up calling Generator.initialize in Rails actionpack lib/action_dispatch/routing/route_set.rb. This method uses sub! to modify the controller name in-place. This ostensibly should not be a problem, because the url method dups the options before passing it along. However, if a string is modified in-place even in a dup-ed Hash, the original Hash is still modified, as the following example shows:

1.9.3p327 :023 >   a = {:key1 => 'foo', :key2 => 'bar'}
 => {:key1=>"foo", :key2=>"bar"} 
1.9.3p327 :024 > b = a.dup
 => {:key1=>"foo", :key2=>"bar"} 
1.9.3p327 :025 > b[:key1].sub! 'foo', 'baz'
 => "baz" 
1.9.3p327 :026 > b
 => {:key1=>"baz", :key2=>"bar"} 
1.9.3p327 :027 > a
 => {:key1=>"baz", :key2=>"bar"} 

Suggestion

A simple dup of the options passed in to will_paginate is not sufficient. The values will need to be dup-ed as well.

Workaround

The controller param should be specified as a symbol, instead of a string as follows:

...
will_paginate @collection, params: {controller: :'/pages', action: 'index'}
...
@mislav
Owner

Good job on the investigative work! Seems like you should send the Rails team a pull request. In the meantime we could work around this in will_paginate I guess

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.