1

所以这是一口。

让我们假设您是汽车制造商,并且您想要一个 Web 应用程序。该 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 年)。

提前感谢您的宝贵时间。

4

1 回答 1

0

因此,在继续阅读之后(并决定从外部页面重新阅读 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-10-10T17:50:16.077 回答