Что такое класс ассоциации, основанный только на атрибуте внешнего ключа?
Короткие: у меня есть атрибут внешнего ключа и вы хотите знать, что такое класс (или ссылочная таблица) этого поля внешнего ключа.
Context:
для двух таблиц: users(id, [other fields])
и issues(id, user_id, assigned_to, [other fields])
Вот моя активная запись о проблеме (нерелевантные части извлекаются)
class User < ActiveRecord::Base
...
end
class Issue < ActiveRecord::Base
belongs_to :user
belongs_to :assigned_user, :foreign_key => 'assigned_to', :class_name => 'User'
...
end
Я хочу сделать доступную для чтения запись изменений. например при изменении назначенного пользователя я хочу получить такое сообщение: Assigned to is changed from Otto to Zoltan
. Функция ActiveRecord имеет функцию changes
, которая является хорошей отправной точкой, но она дает мне только ссылочные идентификаторы. Чтобы перевести на имена, мне нужно прочитать пользователя по id.
Для ассоциации :user
это довольно просто, потому что я должен следовать только соглашениям. Но как получить такую же информацию для атрибута assigned_to
(я хочу сделать общее решение)? Можно ли выяснить, есть ли у нас ассоциация для данного атрибута? Можем ли мы извлечь класс этой ассоциации?
Ответы
Ответ 1
Спасибо. Вот окончательное решение для конкретной проблемы (для обучения):
def textalize_changes
if changed?
r = ""
changes.keys.each do |k|
r << "#{k.humanize} changed "
r << "from `#{translate(k,changes[k][0])}` "
r << "to `#{translate(k,changes[k][1])}`"
r << "<br/>"
end
r
end
end
def translate(attr_name, attr_value)
ass = self.class.reflect_on_all_associations(:belongs_to).reject{|a| attr_name != a.primary_key_name}
if 1 == ass.length and !attr_value.blank?
obj = ass[0].klass.find(attr_value)
obj.send(:name)
else
attr_value
end
end
Ответ 2
Во-первых, вы можете использовать reflect_on_association
для получения метаданных для нужной вам ассоциации. Затем из его результата (который является потомком MacroReflection
) вы можете узнать класс:
reflection = Issue.reflect_on_association(:assigned_user)
reflection.class # => ActiveRecord::Reflection::AssociationReflection
reflection.class_name # => 'User'
Обратитесь к документам здесь и там.