3

有性病课程:

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,通过 SecondTypePageController 处理 SecondTypePage?

IE

user/1/page/2 由:如果“page 2”类型为“FirstTypePage”,则由 FirstTypePageController 处理,如果“page 2”类型为“SecondTypePage”,则由 SecondTypePageController 处理?

更新:我的解决方案:

  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

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

4

2 回答 2

1

我可以看到一个选项 - 在 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

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

显示.html.haml:

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

编辑:

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

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

于 2011-12-12T15:53:19.613 回答
0

you can do it with before_filter, but separating STI models into different controllers isn't good solution. I totally agree with next quote

This may not always apply, but I have yet to see a case where STI works well with multiple controllers. If we are using STI, our objects share a set of IDs and attributes, and therefore should all be accessed in basically the same way (find by some attribute, sort by some attribute, restrict to administrators, etc). If presentation varies greatly we may want to render different model-specific views from our controller. But if object access varies so much that it suggests separate controllers, then STI may not have been the correct design choice.

took here http://code.alexreisner.com/articles/single-table-inheritance-in-rails.html

于 2011-12-12T16:09:54.263 回答