我有一个名为Todo.rb
的模型,它有一个名为“asset
”的属性,它是一个字符串。该字符串包含模型的名称,例如Call
,Email
等
它们还包含asset_id
,它是ActiveRecord中资产的特定记录。
如果从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 :(得分:3)
我理解你在这里要做的事情,并且有一种更简单的方法。它被称为多态性。你希望todo能够属于多种类型的东西 - 有时是电话,有时是电子邮件,等等。好消息是,你已经非常接近了。这是你如何设置它。
在迁移中,将“asset”字段重命名为“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
在要归属于许多不同类型对象的类中,您有一个asset_type字符串列和一个asset_id整数列。并指定它属于多态关联,如上所示。然后,在所有可以有多个todo的模型中,添加:as => :asset
部分告诉它Rails如何找到相关的待办事项。
这很简单,现在它的工作方式与其他任何has_many一样。我希望这有帮助!
更新:这是我写的一篇文章,不仅在模型级别,而且在整个网站的表单中都说明了多态性:
http://kconrails.com/2010/10/19/common-addresses-using-polymorphism-and-nested-attributes-in-rails/
答案 1 :(得分:2)
Rails有一个内置的名为constantize,应该可以解决这个问题:
asset = "Call".constantize.find(2)
你也可以使用Kernel.const_get("Call")
或eval("Call")
,但如果可能,我会避免使用eval。
答案 2 :(得分:2)
asset = todo.asset.capitalize.constantize.find(todo.asset_id)