[英]Rails Sti: single path, different controller
有STI课程:
class Page < ActiveRecord::Base
belongs_to :user
end
class FirstTypePage < Page
end
class SecondTypePage < Page
end
每个班级的控制器,
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.