Rails Sti:单路径,不同的控制器

有STI课程:

class Page < ActiveRecord::Base belongs_to :user end class FirstTypePage < Page end class SecondTypePage < Page end 

每个class级的控制器,

 class PageController < AplicationCorroller end class FirstTypePageController < PageController end class SecondTypePageController < PageController end 

和路线:

 resources :user resource :page end 

如何通过FirstTypePageController处理FirstTypePage,SecondTypePage由单一路径上的SecondTypePageController处理?

user / 1 / page / 2由以下处理:FirstTypePageController如果“page 2”类型是“FirstTypePage”,则通过SecondTypePageController如果“page 2”类型是“SecondTypePage”?

更新:我的解决方案:

  match 'user/:user_id/page/:action', :controller=>'page/first_type_page', :constraints=>PageConstraints.new('FirstTypePage') match 'user/:user_id/page/:action', :controller=>'page/second_type_page', :constraints=>PageConstraints.new('SecondTypePage') class PageConstraints @@cache ||= {} def initialize o_type #@mutex = Mutex.new @o_type = o_type end def matches?(request) user_id = request.params[:user_id] #add Mutex lock here unless page_type = @@cache[user_id] page_type = User.find(user_id).do_some_magik_to_suggest_type @@cache[page_id] = page_type @@cache.shift if @@cache.size > 1000 end page_type == @o_type end end 

我认为这个解决方案可以在少量页面类型上快速运行,我们可以管理内存大小,用于大量页面上的路由

我可以看到一个选项 – 在routes.rb中预加载所有页面并为每个页面定义特殊路由。

 resources :users do |user| Page.all do |page| if page.first_type? # ... routes to first_type_page_controller else # ... end end 

另一种解决方案可能是在PageController使用策略模式(不需要使用FirstTypePageController和其他)。

pages_controller.rb:

 before_filter :choose_strategy def show @strategy.show end private def choose_strategy @strategy = PagesControllerStrategy.new(self, page) end def page @page ||= Page.find params[:id] end 

pages_controller_strategy.rb:

 class PagesControllerStrategy def initialize(controller, page) @controller = controller @page = page end def show # do what you what with controller and page end end 

但是,我建议您仅在视图级别拆分行为:

show.html.haml:

 - if page.first_type? = render 'pages/first_type' - else // ... 

编辑:

我刚刚找到了另一种解决方案,可以帮助你 – 自定义约束。 http://railsdispatch.com/posts/rails-3-makes-life-better

我不确定这是否适用于您的情况,但我认为值得更多地使用路线。

你可以用before_filter来做,但将STI模型分成不同的控制器并不是一个好方法。 我完全同意下一个引用

这可能并不总是适用,但我还没有看到STI适用于多个控制器的情况。 如果我们使用STI,我们的对象共享一组ID和属性,因此应该以基本相同的方式访问它们(按某些属性查找,按某些属性排序,限制管理员等)。 如果演示文稿变化很大,我们可能希望从控制器渲染不同的模型特定视图。 但是如果对象访问变化太大以至于它建议单独的控制器,那么STI可能不是正确的设计选择。

在这里http://code.alexreisner.com/articles/single-table-inheritance-in-rails.html