2010-11-04 80 views
1

我有一個叫做Todo.rb的模型,它有一個名爲「asset」的屬性,它是一個字符串。該字符串包含模型的名稱,例如Call,Email等。如何從字符串中獲取模型類?

它們還包含asset_id,它是ActiveRecord中Asset的特定記錄。

從Todo記錄中,我可以從實際的ActiveRecord類中分配到asset

=> #<Todo id: 165, created_at: "2010-11-04 00:49:45", updated_at: "2010-11-04 00:49:45", contact_id: 49, user_id: 1, asset: "Call", asset_id: 2, original_date: "2010-11-18", current_date: "2010-11-18", done_date: nil> 

由此,我想asset是等價的:

asset = Call.find(2) 

我理解概念,這可能是單表繼承的情況下,但我不清楚如何,我想從用例中構建它。

+0

我想我想通了使用constantize ...但仍在播放 – Angela 2010-11-04 01:37:36

+0

這不是STI(單表繼承) - 多態是不同的。 STI是當多個模型密切相關時,因此在數據庫中共享一個表。 STI是Rails暫時唯一的繼承答案。 – 2010-11-04 02:45:04

回答

3

我明白你要在這裏做什麼,而且有一個更簡單的方法來做到這一點。它被稱爲多態性。你想讓todo能夠屬於多種類型的東西 - 有時候是電話,有時候是電子郵件等等。好消息是,你已經很接近了。這是你如何設置它。

在遷移,重命名爲「資產」字段「ASSET_TYPE」:

rename_column :todos, :asset, :asset_type 

現在添加到您的機型:

class Todo < ActiveRecord::Base 
    belongs_to :asset, :polymorphic => true 
end 

class Call < ActiveRecord::Base 
    has_many :todos, :as => :asset 
end 

class Email < ActiveRecord::Base 
    has_many :todos, :as => :asset 
end 

在這是要belong_to許多不同類對象的類型,您有一個asset_type字符串列和一個asset_id整數列。並且您指定它屬於多態關聯,如上所示。然後,在所有可以擁有待辦事項的模型中,添加:as => :asset部分以告訴Rails如何查找關聯的待辦事項。

這非常簡單,現在它和其他has_many一樣工作。我希望這有幫助!

UPDATE:這是我寫了一篇文章,說明多態性不只是在模型級別,而且在整個網站的形式:

http://kconrails.com/2010/10/19/common-addresses-using-polymorphism-and-nested-attributes-in-rails/

+0

我一直在尋找多態的解釋 - 我做了constantize的快捷方式,但我會開始更深入地研究多態,但即使有實用的編程教程,我也總是難以理解....謝謝。 – Angela 2010-11-04 15:16:10

+0

沒問題!我認爲多態性對於我來說很難掌握,直到我第一次真正需要它爲止 - 就像在您的情況下需要將todo添加到多種類型的事物,而沒有像call_todo,email_todo等模型一樣。你的例子是一個很好的用例。 – 2010-11-04 16:20:03

2

Rails有一個內置的叫constantize應該做的伎倆:

asset = "Call".constantize.find(2) 

您還可以使用Kernel.const_get("Call")eval("Call"),但我會避免EVAL如果在所有可能的。

+0

是的,那是有效的---在我使用這個和@Sam's之後會得分 - 但自從*有一天*給了polymoprhism一點*我會遷移到那個,但是現在只需要一些工作和繼續。 – Angela 2010-11-04 15:16:59

2
asset = todo.asset.capitalize.constantize.find(todo.asset_id) 
+0

謝謝 - 這個作品...我偶然發現了 - 我指出多態性的答案,因爲我認爲*最終我將不得不去那裏,而不是使用send方法並計算出來,但現在這個更清晰了。 – Angela 2010-11-04 15:17:41

相關問題