簡體   English   中英

Rails Sti:單路徑,不同的控制器

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM