Как я могу получить класс модели из строки? - PullRequest
1 голос
/ 04 ноября 2010

У меня есть модель с именем Todo.rb, которая имеет атрибут с именем "asset", который является строкой. Строка содержит имена моделей, такие как Call, Email и т. Д.

Они также содержат asset_id, который является конкретной записью Актива в ActiveRecord.

Как из записи Todo я могу присвоить asset из этого фактического класса ActiveRecord?

=> #<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)

Концептуально я понимаю, что это может быть случаем наследования одной таблицы, но мне неясно, как, и я хотел создать его из варианта использования.

Ответы [ 3 ]

3 голосов
/ 04 ноября 2010

Я понимаю, что вы пытаетесь сделать здесь, и есть гораздо более простой способ сделать это. Это называется полиморфизмом. Вы хотите, чтобы вы могли принадлежать к нескольким типам вещей - иногда к звонкам, иногда к электронной почте и так далее. Хорошая новость в том, что вы уже достаточно близки. Вот как вы это настроили.

В вашей миграции переименуйте поле "актив" в "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. И вы указываете, что он принадлежит к полиморфной ассоциации, как показано выше. Затем во всех моделях, которые могут иметь to_many задачи, вы добавляете часть :as => :asset, чтобы сообщить Rails, как найти связанные задачи.

Это очень просто, и теперь оно работает так же, как и любой другой has_many. Надеюсь, это поможет!

ОБНОВЛЕНИЕ: Это статья, которую я написал, которая иллюстрирует полиморфизм не только на уровне модели, но и во всех формах вашего сайта:

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

2 голосов
/ 04 ноября 2010
 asset = todo.asset.capitalize.constantize.find(todo.asset_id)
2 голосов
/ 04 ноября 2010

В Rails есть встроенная функция constantize, которая должна помочь:

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

Вы также можете использовать Kernel.const_get("Call") или eval("Call"), но я бы избегал eval, если это возможно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...