will_paginate
will_paginate copied to clipboard
no matching route error even though route exists
This works fine:
<%= link_to 'events', fullcalendar_engine_path %>
because I specified the route in routes.rb:
mount FullcalendarEngine::Engine , at: "/fullcalendar_engine"
resources :events, module: 'fullcalendar_engine' , only: [:index, :show] do
collection do
get 'calendar', to: 'events#index', as: 'calendar'
end
end
Yet when I try to generate a path to /fullcalendar_engine using will_paginate:
<%= will_paginate table.collection, :params => { controller: fullcalendar_engine_path, action: 'index' } %>
I get the following error:
No route matches {:action=>"index", :controller=>"fullcalendar_engine", :id=>"56721d6f6d61632e8c020000", :page=>2}
Why would it give this error when the route exists?
I think this issue is related to #172
The problem is related to the url scope when you create an engine you have 2 url sets, for example Rails.application.routes
the appllication url scoupe and FullcalendarEngine::Engine.routes
the engine url scope. You can experiment in console with FullcalendarEngine::Engine.routes.url_for( ... )
and Rails.application.routes.url_for( ... )
will_paginate by default user application scope to create the paginate urls.
I found 2 possible solutions. Use subclass WillPaginate::ActionView::LinkRenderer, override the method url and using an extra option to pass your engine url scope, for example:
class CustomLinkRenderer < WillPaginate::ActionView::LinkRenderer
def url(page)
@base_url_params ||= begin
url_params = merge_get_params(default_url_params)
url_params[:only_path] = true
merge_optional_params(url_params)
end
url_params = @base_url_params.dup
add_current_page_param(url_params, page)
if @options[:url_scope]
@options[:url_scope].url_for(url_params)
else
@template.url_for(url_params)
end
end
end
And then in the view:
<%= will_paginate table.collection, renderer: CustomLinkRenderer, url_scope: FullcalendarEngine::Engine.routes %>
Or the other option is passed all engine routes to the application url scope, like this:
# app/controllers/application_controller.rb
module Emerald
class ApplicationController < ActionController::Base
helper FullcalendarEngine::Engine.routes.url_helpers
include FullcalendarEngine::Engine.routes.url_helpers
# ..
end
end
Unfortunately, neither of these solutions worked for me.
FullcalendarEngine::Engine.routes.url_for({ controller: 'events', action: 'index'})
ActionController::UrlGenerationError: No route matches {:action=>"index", :controller=>"events"}
RailsDevise::Application.routes.url_for({ controller: 'events', action: 'index'})
ActionController::UrlGenerationError: No route matches {:action=>"index", :controller=>"events"}