【问题标题】:How to get url_for working with a module?如何让 url_for 使用模块?
【发布时间】:2016-07-22 21:48:29
【问题描述】:

我已经在我的 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: No route matches {:action=>"index", :controller=>"events"}
FullcalendarEngine::Engine.routes.url_for({ controller: 'events', action: 'index'})
=> ActionController::UrlGenerationError: No route matches {: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

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

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

如何让url_for 识别路线?

【问题讨论】:

    标签: ruby-on-rails


    【解决方案1】:

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

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

    此外,您发布的路线不包括index 的路线,因此它可能不存在。如果是这样,它可能不需要id

    【讨论】:

    • 其实我最初并没有发布所有的路线。确实有索引路线。我更新了问题。
    【解决方案2】:

    对于遇到此问题的任何其他人。我逐步浏览了 Rails 代码,这就是为我解决的问题:

    FullcalendarEngine::Engine.routes.url_for({:action=>"index", host: "localhost"}, 'fullcalendar_engine_path')
    

    【讨论】:

      【解决方案3】:

      看起来 5 年前提出的问题可能仍然非常相关。我希望您已经找到了解决方案。 :)

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

      我偶然发现了这一系列问题和 cmets:

      长话短说,这个丑陋的 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 中的一些深层魔法产生令人讨厌的冲突!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-10-30
        • 2018-06-23
        • 1970-01-01
        • 1970-01-01
        • 2013-11-16
        • 2010-11-29
        • 2016-10-31
        • 2019-03-15
        相关资源
        最近更新 更多