Подтвердить что ты не робот

Что такое класс ассоциации, основанный только на атрибуте внешнего ключа?

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

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 (я хочу сделать общее решение)? Можно ли выяснить, есть ли у нас ассоциация для данного атрибута? Можем ли мы извлечь класс этой ассоциации?

4b9b3361

Ответ 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'

Обратитесь к документам здесь и там.