【问题标题】:What is the class of an association based on the foreign key attribute only?仅基于外键属性的关联类是什么?
【发布时间】:2010-07-13 07:28:20
【问题描述】:

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

上下文:

给定 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 属性获取相同的信息(我想做一个通用的解决方案)?是否有可能弄清楚我们是否对给定的属性有关联?我们可以提取该关联的类吗?

【问题讨论】:

    标签: ruby-on-rails activerecord


    【解决方案1】:

    首先,您可以使用reflect_on_association 获取所需关联的元数据。然后,从它的结果(这是一个MacroReflection 后代)中,您可以找到该类:

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

    请参阅文档 herethere

    【讨论】:

    • 您的文档链接无效。另外,有没有办法获得完整的命名空间?像'MyModule::User'
    • 啊,你可以做reflection.klass来获取命名空间。
    【解决方案2】:

    谢谢。下面是针对具体问题的最终解决方案(供学习):

      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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-09-18
      • 2012-08-23
      • 2016-10-31
      • 1970-01-01
      • 2020-01-12
      • 1970-01-01
      • 2016-01-31
      • 1970-01-01
      相关资源
      最近更新 更多