will_paginate icon indicating copy to clipboard operation
will_paginate copied to clipboard

no matching route error even though route exists

Open JohnMerlino1 opened this issue 9 years ago • 3 comments

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?

JohnMerlino1 avatar Jan 15 '16 18:01 JohnMerlino1

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

artero avatar Jan 27 '16 05:01 artero

Unfortunately, neither of these solutions worked for me.

JohnMerlino1 avatar Jul 22 '16 20:07 JohnMerlino1

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"}

JohnMerlino1 avatar Jul 22 '16 21:07 JohnMerlino1