如何让url_for使用模块?

时间:2016-07-22 21:48:29

标签: ruby-on-rails

我在我的routes.rb中安装了FullcalendarEngine:

mount FullcalendarEngine::Engine , at: "/fullcalendar_engine"

不幸的是,即使我在routes.rb中有这个:

resources :events,  module: 'fullcalendar_engine'

生成的路线:

fullcalendar_engine_path                    /fullcalendar_engine        FullcalendarEngine::Engine
events_path                     GET         /events/index(.:format)     fullcalendar_engine/events#index
event_path                      GET         /events/:id(.:format)       fullcalendar_engine/events#show
events_path                     GET         /events(.:format)           fullcalendar_engine/events#index
                                POST        /events(.:format)           fullcalendar_engine/events#create
new_event_path                  GET         /events/new(.:format)       fullcalendar_engine/events#new
edit_event_path                 GET         /events/:id/edit(.:format)  fullcalendar_engine/events#edit
event_path                      GET         /events/:id(.:format)       fullcalendar_engine/events#show
                                PATCH       /events/:id(.:format)       fullcalendar_engine/events#update
                                PUT         /events/:id(.:format)       fullcalendar_engine/events#update
                                DELETE      /events/:id(.:format)       fullcalendar_engine/events#destroy

我仍然无法使用url_for(我需要这样做才能使其与will_paginate一起使用):

错误:

  

RailsDevise :: Application.routes.url_for({controller:' events',action:' index'})       => ActionController :: UrlGenerationError:没有路由匹配{:action =>" index",:controller =>" events"}       FullcalendarEngine :: Engine.routes.url_for({controller:' events',action:' index'})       => ActionController :: UrlGenerationError:没有路由匹配{:action =>" index",:controller =>" events"}

当我检查模块的路线时:

FullcalendarEngine::Engine.routes.routes.collect {|journey| journey.defaults }
 => [{:controller=>"fullcalendar_engine/events", :action=>"index"}, {:action=>"get_events", :controller=>"fullcalendar_engine/events"}, {:action=>"move", :controller=>"fullcalendar_engine/events"}, {:action=>"resize", :controller=>"fullcalendar_engine/events"}, {:action=>"index", :controller=>"fullcalendar_engine/events"}, {:action=>"create", :controller=>"fullcalendar_engine/events"}, {:action=>"new", :controller=>"fullcalendar_engine/events"}, {:action=>"edit", :controller=>"fullcalendar_engine/events"}, {:action=>"show", :controller=>"fullcalendar_engine/events"}, {:action=>"update", :controller=>"fullcalendar_engine/events"}, {:action=>"update", :controller=>"fullcalendar_engine/events"}, {:action=>"destroy", :controller=>"fullcalendar_engine/events"}] 

注意它有这个:

@defaults={:controller=>"fullcalendar_engine/events", :action=>"index"}

注意控制器值的命名空间。这不起作用:

FullcalendarEngine::Engine.routes.url_for({:controller=>"events", :action=>"index"})
ActionController::UrlGenerationError: No route matches {:action=>"index", :controller=>"events"}

但是如果我尝试命名它,它就会出现这个错误:

FullcalendarEngine::Engine.routes.url_for({:controller=>"fullcalendar_engine/events", :action=>"index"})
ArgumentError: Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true

即使添加主机也会生成错误的网址:

FullcalendarEngine::Engine.routes.url_for({:controller=>"fullcalendar_engine/events", :action=>"index", host: "localhost"})
 => "http://localhost/fullcalendar_engine/" 

如何让url_for识别路线?

3 个答案:

答案 0 :(得分:0)

您的路线需要id参数,因此您需要给它一个:

url_for(controller: 'events', action: 'show', id: 5)   # < Notice the `id`

此外,您发布的路线不包含index的路线,因此可能不存在。如果确实如此,它可能不需要id

答案 1 :(得分:0)

对于遇到此问题的其他任何人。我逐步完成了Rails代码,这对我来说是固定的:

elif

答案 2 :(得分:0)

看起来 5 年前提出的问题可能仍然具有相关性。我希望你已经找到了解决办法。 :)

我在 Rails 6.0.3 中遇到了类似的问题(有点旧,是不是?),其中 url_for 爆炸了以非常相似的方式用于来自非隔离引擎的控制器,继承自 ::ApplicationController

我偶然发现了这一系列的问题和评论:

长话短说,这个丑陋的 hack 可能会暂时拯救你,直到你升级到更新的 Rails:

class Foo::BarController < ::ApplicationController

  # your normal stuff

  private

  def _routes # <- this overrides an inherited method, so keep the name!
    @_routes || my_engine_routes
  end

  def my_engine_routes # <- and this you can name as you want
    @_my_engine_routes ||= Foo::Engine.routes
  end
end

请务必仔细测试它是否适合您的情况,并且在升级后不要忘记将其删除。它可能会与 Rails 中的一些深奥的魔法造成严重的冲突!