仅基于外键属性的关联类是什么?

时间:2010-07-13 07:28:21

标签: ruby-on-rails activerecord

简短:我有一个外键属性,想知道该外键字段的类(或引用表)是什么。

上下文:

给出了2个表: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-s。要翻译成名称,我需要通过id读取用户。

对于关联:user,这很容易,因为我必须遵循惯例。但是如何获取assigned_to属性的相同信息(我想制作一般解决方案)?是否有可能弄清楚我们是否有给定属性的关联?我们可以提取该关联的类吗?

2 个答案:

答案 0 :(得分:32)

首先,您可以使用reflect_on_association获取所需关联的元数据。然后,根据其结果(MacroReflection后代),您可以找到该类:

reflection = Issue.reflect_on_association(:assigned_user)
reflection.class # => ActiveRecord::Reflection::AssociationReflection
reflection.class_name # => 'User'

请参阅文档herethere

答案 1 :(得分:3)

谢谢。以下是特定问题(学习)的最终解决方案:

  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