首页 > 解决方案 > 如何迭代 ActiveRecord 对象的关联对象

问题描述

我需要对 Rails 5 ActiveRecord 对象的所有关联对象执行操作,但我不想为每个对象显式编写单独的方法调用。
例如,假设“假期”是我正在处理的对象,它可能有许多关联的对象(为简单起见,我们假设所有对象都是 has_one):代理、旅行者、飞机、船舶、酒店。我可以做:

do_stuff_to_assoc_object(vacation.agent)

do_stuff_to_assoc_object(vacation.traveler)

do_stuff_to_assoc_object(vacation.plane) ...等。

但这很不雅,尤其是在有很多关联的情况下。感谢如何从 ActiveRecord 对象中获取所有关联模型? ,我知道我可以将关联对象的模型类名称作为字符串或 AssociationReflection 对象获取,但是如何获取它们所代表的实际对象呢?

   parent_object.reflect_on_all_associations(:has_one).map(&:class_name).each do |model_name|
      ### how to convert model_name into the object? 
      do_stuff_to_assoc_object(obj)
    end

  def do_stuff_to_assoc_object(obj)
     # I do things to the associated object here
  end

标签: ruby-on-railsactiverecord

解决方案


如果您获取关联模型, 可以使用public_send将模型名称转换为对象,请检查以下内容:

parent_object.reflect_on_all_associations(:has_one).map(&:class_name).each do |model_name|
      # assuming that parent_object is the object that has all associations.
      obj = parent_object.public_send(model_name)
      do_stuff_to_assoc_object(obj)
    end

  def do_stuff_to_assoc_object(obj)
     # I do things to the associated object here
  end

根据@Clemens Kofler的评论,为避免重复迭代,我们可以删除 .map 如下:

parent_object.reflect_on_all_associations(:has_one).each do |association|
          # assuming that parent_object is the object that has all associations.
          obj = parent_object.public_send(association.class_name)
          do_stuff_to_assoc_object(obj)
        end

      def do_stuff_to_assoc_object(obj)
         # I do things to the associated object here
      end

参考:
https ://apidock.com/ruby/Object/public_send


推荐阅读