【问题标题】:rails routes and custom routing for nested resource嵌套资源的rails路由和自定义路由
【发布时间】:2014-08-22 22:21:25
【问题描述】:

对于几个项目,我需要一些东西来简化我的路线,以删除最重要路线之一的控制器名称。在这种情况下,版本,所以而不是

domain.com/editions/london/venues/the-venue

我们使用->

domain.com/london/venues/the-venue

我一直在使用这个公式进行路由:

  # MUST BE LAST
  resources :editions, path: '' do
    get 'set_session', on: :member
    resources :events
    resources :quiz_masters
    resources :venues
  end

它运行良好,但我觉得它有一些不愉快的地方。我想知道是否有更好的选择,它也有限制,所以我不必担心总是把它放在我的路线底部。

我也不确定path: '' 是一个好方法吗?即使它有效。

【问题讨论】:

  • 例如,我可以用:constraints => proc { |req| Edition.all.map(&:slug).include?(req.params[:edition_id]) } 以某种方式限制它?
  • 这也是我们一直在努力解决的问题 - 如果您有一个希望在您的路线中不使用资源定义的单一实例,我们拥有的最佳解决方案就是您在问题中提出的解决方案本身
  • 是的,感觉有点像黑客。一方面,我不喜欢使用 path: "" 打开所有路由,另一方面,我不喜欢在我的路由中设置一个必须触及数据库的约束的想法!脏!
  • 为你写答案。对你帮助不大,但会解释一些事情

标签: ruby-on-rails ruby-on-rails-4 routes nested-routes custom-routes


【解决方案1】:

使用您的示例,您可能应该限制它。使用您包含的 Edition.all.map(&:slug) 数组或以某种方式缓存它,具体取决于列表的大小。这样它就会受到限制,并且不一定需要位于路由文件的底部。

resources :editions, path: '', :constraints => proc { |req| ['london', 'other_cities'].include?(req.params[:edition_id]) } do
  get 'set_session', on: :member
  resources :events
  resources :quiz_masters
  resources :venues
end

【讨论】:

    【解决方案2】:

    路线

    如果你的答案有问题,我会详细说明我们是如何做到这一点的,也就是说我们所做的和你在问题中解释的完全一样:

    #config/routes.rb
    ... @bottom
    resources :events, path: "" do
       resources :venues
       # ...
    end
    

    这仅适用于单个资源(您不能拥有多个 path: ''),因为如果您有多个引用,它将发生冲突。正如您所提到的,这应该在您的路线的底部(甚至低于root)。我们目前使用此设置


    App-Wide Slugs

    您可能会从中受益的是创建某种方法来处理应用程序范围内的 slugs

    我们还没有这样做,但理论上可以通过使用具有多态关联的某种中间件/简单模型来确定将请求路由到何处来处理。

    例如,根据引用的问题,您可能能够拥有如下模型:

    #app/models/slug.rb
    Class Slug < ActiveRecord::Base
       belongs_to :sluggable, polymorphic: true
    end
    
    #slugs table
    id | sluggable_id | sluggable_type | created_at | updated_at
    

    然后您可以像这样处理模型的 slug:

    #app/models/concerns/slugged.rb
    Class Slugged
        extend ActiveSupport::Concern
    
        included do
           has_one :slug, as: :sluggable
           before_save :build_slug
        end
    end
    

    这应该允许您随后在一些 slug 中间件中获取 slug,并路由到正确的控制器。可能是“黑客”,但它是最广泛和模块化的方式

    【讨论】:

      【解决方案3】:

      在我看来,尴尬来自于需求和路由和 URL 的线性特性,而不是来自您的解决方案。正如您所说,关于该代码(与 Rich 的相同)的某些内容感觉有点不愉快,而且可能“不是 Rails 方式”;但是 Rails 意味着在必要时弯曲,我想不出更有效的方法来完成你正在做的事情。

      如果路由中的第一项是 slug ("/london/"),则必须最后定义路由。我想不出有什么办法解决这个问题,而且不认为你应该失去任何睡眠或安心寻找替代方案。

      任何有趣的应用程序都会突破其编写框架的限制,这意味着总会有一些尴尬的代码。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-01-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-04-05
        • 2011-05-23
        • 1970-01-01
        相关资源
        最近更新 更多