【问题标题】:rails 3 polymorphic routingrails 3 多态路由
【发布时间】:2012-06-11 09:47:10
【问题描述】:

一段时间以来一直在努力寻找这个问题的答案,觉得值得提出一个新问题...

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

我有一个基TransportController,然后Transport的每一个类型都有一个对应的控制器(都在Transport命名空间下),即Transport::CarControllerTransport::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"

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

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 model-view-controller polymorphism rails-routing


    【解决方案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 routes——从长远来看,它们可能会让你的生活更轻松。

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        猜你喜欢
        • 2011-05-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多