2

一段时间以来一直试图找到这个问题的答案,决定值得问一个新的......

我有多个多态模型,定义如下:class Transport, class Transport::Car < Transport,class Transport::Plane < Transport

我有一个 base TransportController,然后每种类型Transport都有一个相应的控制器(都在Transport命名空间下),即Transport::CarController, Transport::PlaneController

我想弄清楚如何为不同的Transport操作创建路由......

  • 我事先不知道我将拥有多少Transport个子类(这是通过数据库调用作为初始化程序的一部分完成的)。
  • 对于每个Transport,都有两个共享控制器操作,分别调用它们#board#depart。这些方法应该存在于内部TransportController,因为它们执行相同的操作并显示相同的视图,而与 Transport 的类型无关。
  • 不同Transport的类型可以对自己的操作有不同的实现。例如#choose_seat对于汽车和飞机来说,不同的约束和不同的视图是不同的,但动作是相同的。
  • 不同Transport的类型有权有独特的行动。例如Transport::PlaneController应该有一个#landing_gear_up动作,而这对于Transport::CarController.

我可能喜欢的是一个路由文件,例如:

# for an action landing_gear_up only inside plane
match '/transport/plane/landing_gear_up',
      :controller => "Transport::PlaneController",
      :action => "landing_gear_up"

# for an action on every transport type that are handled differently
match '/transport/:type/choose_seat',
      :controller => "Transport::<type>Controller",
      :action => "choose_seat"

# for the actions that are handled commonly across every type of transport
match '/transport/:type/board', :to => "transport#board"
match '/transport/:type/depart', :to => "transport#depart"

我觉得这应该可以通过“动态细分”实现,但我无法让它正常工作。有什么建议么?

4

2 回答 2

1

routes.rb您可以在其中定义可以使代码更加干燥的方法和变量。我将如何尝试这样做的一个例子:

Your::Application.routes.draw do
  ## other routes

  ## helper method to define transport route
  def route_transport action, types
    match "/transport/:type/#{action}", :to => "transport##{action}" and return if types == :common
    [types].flatten.each { |t| match "/transport/#{t}/#{action}", :controller => "Transport::#{t}Controller", :action => action }
  end

  {
    :board => :common,
    :depart => :common,
    :landing_gear_up => :plane,
    :choose_seat => [:car, :plane],
    # action name => :common or transport type(s)
  }.each { |action, types| route_transport action, types }

  ## other routes
end

我没有检查代码,它可能包含错误。运行rake routes检查是否正在生成正确的路由。

另外,看看RESTful 路由——从长远来看,它们可能会让你的生活更轻松。

于 2012-06-07T11:44:32.173 回答
0

如果您在控制器中具有相同的继承层次结构,那么您不必做任何特别的事情。只需声明资源,为每个控制器声明非 RESTful 路由即可。PlaneController#board 会自动调用 TransportController#board。特定于 PlaneController 的操作将保持特定于该控制器。

于 2012-06-08T01:37:32.957 回答