开发者

How can I get a model class from a string?

开发者 https://www.devze.com 2023-01-23 04:40 出处:网络
I have a Model called Todo.rb which has an attribute called \"asset\" which is a string.The string contains the names of Models such as Call, Email, etc.

I have a Model called Todo.rb which has an attribute called "asset" which is a string. The string contains the names of Models such as Call, Email, etc.

They also contain an asset_id, which is a specific record of the Asset in ActiveRecord.

How, from a Todo record, can I assign to asset from that actual ActiveRecord class?

=> #<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-1开发者_如何学JAVA8", current_date: "2010-11-18", done_date: nil>

From this, I would like asset to be the equivalent of:

 asset = Call.find(2)

I understand conceptually this could be a case of single table inheritance, but I wasn't clear how and I wanted to build it up from the use-case.


I understand what you're trying to do here, and there's a much simpler way to do it. It's called polymorphism. You want todo's to be able to belong to more than one type of thing - sometimes a call, sometimes email, and so on. The good news is, you're pretty close already. Here's how you set it up.

In your migration, rename the "asset" field to "asset_type":

rename_column :todos, :asset, :asset_type

Now add this to your models:

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

In the class that is going to belong_to many different types of objects, you have an asset_type string column, and an asset_id integer column. And you specify that it belongs to the polymorphic association, as shown above. Then, in all the models that can have_many todo's, you add the :as => :asset part to tell it Rails how to find the associated todo's.

This is very easy, and now it works just like any other has_many. I hope this helps!

UPDATE: This is an article I wrote that illustrates polymorphism not just at the model level, but also throughout your site's forms:

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


Rails has a built-in called constantize which should do the trick:

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

You can also use Kernel.const_get("Call") or eval("Call") but I would avoid eval if at all possible.


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

精彩评论

暂无评论...
验证码 换一张
取 消