2011-02-24 119 views
8

我有一個基類繼承了2人通過單表繼承。我希望所有的子類都由於各種原因共享相同的控制器/視圖 - 唯一真正的區別在於模型的功能。單控制器,多(繼承)類(軌3)

但是,當我嘗試使用link_to「stuff」,instance_of_child我收到有關無法找到正確頁面的投訴。

我試過與匹配'/ subclass'=>重定向('/ parent')但這樣做會產生無意義的奇怪鏈接。有什麼建議麼?我在rails方面很新穎,我承認我對routes.rb的理解仍然有限 - 但是,我並不完全確定這是我應該看的地方。

回答

12

http://www.alexreisner.com/code/single-table-inheritance-in-rails

如果你曾經嘗試過STI添加到現有 Rails應用程序,你可能 知道很多你 的link_to和方法的form_for拋出 錯誤,當您添加一個父類。 這是因爲ActionPack查看 對象的類來確定其路徑和URL的 ,並且您沒有 爲您的新子類映射路由。 您可以添加路由像這樣,雖然 我不建議這樣做:

# NOT recommended: 
map.resources :cars,  :as => :vehicles, :controller => :vehicles 
map.resources :trucks,  :as => :vehicles, :controller => :vehicles 
map.resources :motorcycles, :as => :vehicles, :controller => :vehicles 

這隻能緩解特定 症狀。如果我們使用form_for,我們的表格 字段仍然沒有我們期望的名稱 (例如:params [:car] [:color] 而不是params [:vehicle] [:color])。 相反,我們應該通過在父類中實現 model_name方法來攻擊 問題的根。 我還沒有看到任何 文檔這種技術,所以這是非常 非官方的,但它是有道理的,它 完全適用於我的Rails 2.3 和3:

def self.inherited(child) 
    child.instance_eval do 
    def model_name 
     Vehicle.model_name 
    end 
    end 
    super 
end 

這可能看起來混亂,所以讓 我解釋一下:

當你調用一個URL生成方法 (如:的link_to(「車」,汽車)),ActionPack的 通話模式l_name在給定對象 的類(此處爲car)。這會返回 一種特殊類型的字符串,它會在網址中確定對象的名稱爲 。所有我們在這裏所做的 重寫MODEL_NAME方法的車輛因此ActionPack的 會看到汽車,卡車和摩托車 子類爲歸屬於母公司 類(汽車),因此使用 父類的命名路線的 子 (VehiclesController)生成的URL爲 的任何地方。這一切都假設你是 使用Rails資源樣式(RESTful) URL。 (如果你不是,請做。)

要自行調查MODEL_NAME 調用,請參閱 的ActionController :: RecordIdentifier#model_name_from_record_or_class 方法Rails的 源代碼。在Rails 2.3的特殊 字符串 的ActiveSupport :: MODELNAME的一個實例,在Rails 3中 這是一個::加載ActiveModel名稱

+0

這正是我一直在尋找。亂搞路由表似乎是一個糟糕的解決方法,是的,我注意到它搞亂了我的表單。所以,只要對上面的例子稍加修改,使其符合我的課程名稱,您的解決方案就可以解決我的問題。你不知道我多麼害怕創建/維護那些額外的控制器。 – user632657 2011-02-24 19:02:47

+0

很高興聽到它! :) – 2011-02-24 19:24:22