【问题标题】:Single Table Inheritance(STI) with Single Controller and Nested Resources: polymorphic_path doesn't match route-generated path具有单控制器和嵌套资源的单表继承 (STI):多态路径与路由生成的路径不匹配
【发布时间】:2013-10-10 15:18:59
【问题描述】:

所以这是一口。

假设您是一家汽车制造商,并且您想要一个用于内容的网络应用程序。该 web 应用程序的一部分用于让您的设计师在他们的设计上进行协作。你设计汽车、卡车和 suv 让我们说。假设您继承了更新这个东西,并且之前的开发人员决定使用单表继承作为设计模式。您阅读了 STI 并同意使用的设计模式是正确的,但您想重构一堆控制器和视图,因为它们实际上是相同的。

您继承的模型如下所示:

class Design < ActiveRecord::Base
class DesignVersion < ActiveRecord::Base

class DesignCar < Design
class DesignCarVersion < DesignVersion

假设您的 SUV 和卡车设计/设计版本的模型遵循此处为汽车列出的相同模式。还假设自从应用程序工作以来已经建立了适当的关系,它只是有一些你试图干掉的冗余代码。

您最初是为汽车、汽车设计、卡车、卡车设计等各配备一个控制器。因此,您阅读了 STI with One Controller 和 STI 路由。结果,您制作了一个 Designs 和 DesignVersions 控制器(以匹配您的 Design 和 DesignVersion 基础模型),并在您的路线中提出如下内容:

resources :cars, :controller => "designs", :type => 'DesignCar' do
  resources :car_versions, :controller => "design_versions", :type => 'DesignCarVersion'
    member do
      post 'approve'
      #various other things besides new, show, etc
    end
  end
end

这有助于生成 new_design_car_car_versions_path、approve_design_car_car_versions_path 等路线。假设您对卡车和 suv 执行相同操作。你做了一个 rake 路线,看看你的路线——这些路线和你之前做的路线是一样的

resources :cars
  resources :car_versions
    member do
      post 'approve'
    end
  end
end

所以一切看起来都很好。您创建了一个仅列出设计的非常基本的视图(因此,如果您转到 /cars,您只会看到汽车设计)并且当您查看 /cars、/trucks 等时,一切看起来都很好。您看到的只是特定类型的设计.然后你开始添加旧的 _paths 并将它们重构为通用而不是特定的。

没问题,你认为。我只会使用 polymorphic_path!

这就是我遇到问题的地方。

从 config/routes.rb 生成的路线生成为approved_design_car_car_versions_path。等效的 polymorphic_path 生成为approved_design_car_design_car_versions_path。当我尝试查看 /cars 的页面(其中列出了每个设计,然后在其下列出了有关各种版本的一些数据,包括指向这些特定设计版本的链接)时,正如人们所期望的那样,它会因为“approve_design_car_design_car_versions_path”不存在。

我们还假设,尽管 DesignCar 和 DesignCarVersion 的模型名称看起来很笨重,但我们也有一个用于 web 应用程序另一部分的 Car 模型。结果,我们不得不区分。对于这个例子,CarDesign 和 CarDesignVersion 可能更有意义,但在我之后建模的问题中,我实际拥有的(我在这里用 DesignCar 替换)更有意义。

我尝试过的事情:

大量阅读。我首先认为 polymorphic_url 可能不是我想要的,所以我尽我所能尝试阅读如何为 STI 生成路由。不幸的是,我发现的大多数答案要么不包含 :type 内容,要么没有像我一样包含嵌套路由。

然后我想也许我真的想从 STI 更改为多态性。我看了一个较旧的 Rails Cast 并阅读了一些内容,但得出的结论是 STI 确实是正确的。

然后我想“好吧,我只需将路由的名称指定为多态生成的任何名称,这应该可以工作”,所以我做了如下的事情:

resources :cars, :controller => "designs", :type => 'DesignCar' do
  resources :car_versions, :controller => "design_versions", :type => 'DesignCarVersion'
    member do
      post 'approve', :as => 'approve_design_car_car_versions'
    end
  end
end

当我做了一个 rake 路线时,它变成了 'approve_design_car_car_versions_design_car_versions'

那么,我需要做些什么才能使生成的路线与我将汽车和 car_version 交给它时生成的 polymorphic_path 匹配?不使用多态路径?修复我的路线?回到我所有孩子的控制器,即使这会产生很多重复?

我怀疑它与返回模型名称的 polymorphic_path 的模型上的反射和反射有关?出于某种原因,正在为路线生成所做的事情是返回其他东西。但是,我很困惑为什么如果这不是一个错误(我假设这不是一个错误,我只是做错了什么)或者我错过了一个我应该是的关键值经过某处。我对 Rails 还比较陌生,所以我相信错误很可能出在我身上(现在大约 1.5 年)。

提前感谢您的宝贵时间。

【问题讨论】:

    标签: ruby-on-rails-3 sti nested-routes


    【解决方案1】:

    所以,在继续阅读(并决定从外部页面重新阅读 Rails 路由,因为我几个月没有这样做了)之后,我找到了以下解决方案:

    resources :cars, :controller => "designs", :type => 'DesignCar' do
      resources :car_versions, :controller => "design_versions", :type => 'DesignCarVersion', :as => 'design_car_version' do
        member do
          post 'approve'
        end
      end
    end
    

    请注意,在上面的问题中,我错过了 :car_versions 上的“do”,但它实际上存在于代码中。解决方案是将 :as 添加到资源级别,而不是添加到每个单独的成员。

    如果有更好的方法,我会全力以赴。

    【讨论】:

      猜你喜欢
      • 2013-01-23
      • 2011-08-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多