处理ActiveRecord :: Reflections - 一些模型反射出现空(Rails 4.2)

时间:2016-08-13 01:51:08

标签: ruby-on-rails activerecord

Rails& ActiveRecord 4.2.1,Ruby 2.2.0

编辑:请注意这个问题主要是为了更好地理解AR和Rails,讨论ActiveRecord的Reflections方面是如何工作的。

我正在研究一个关注ActiveRecord模型的关联,并根据这些关联创建回调。通过对单个文件或示例的测试。但是,在测试完整套件或运行开发服务器时,它会失败,因为某些模型返回nil进行反射。要点:

module CustomActivityMaker
  extend ActiveSupport::Concern

  module ClassMethods
    # @param {Array[Symbols]} assns
    # 'assns' params is a list of a model's associations
    def create_activity_for(assns)

      assns.each do |assn|
        r = self.reflect_on_association(assn)
        if r.is_a?(ActiveRecord::Reflection::ThroughReflection)
          # For a through association, we just track the creation of the join table.
          # byebug
          r.source_reflection.klass  # <== source_reflection unexpectedly ends up being nil
        else
          r.klass
        end
        ...
      end
    end
  end
end

像这样调用:

# models/contact.rb
class Contact < ActiveRecord::Base
  has_many :emails
  has_many :addresses
  has_many :phone_numbers
  has_many :checklists
  has_many :checklist_items, through: :checklists

  create_activity_for :checklist_items

  ...
end

# models/checklist.rb
class Checklist < ActiveRecord::Base
  belongs_to :contact
  has_many :checklist_items
  ...
end

# models/checklist_item.rb
class ChecklistItem < ActiveRecord::Base
  belongs_to :checklist
  has_one :matter, through: :checklist

  ...
end

错误显示在CustomActivityMaker的注释中。使用byebug时,变量r是ActiveRecord :: Reflection :: ThroughReflection。对source_reflection的调用应该是一个ActiveRecord :: Reflection :: HasManyReflection,其中包含&#39; klass&#39;给我ChecklistItem类。

然而:source_reflection出现零。使用byebug检查错误,通过类清单没有任何反射:

Checklist.reflections  # <== {}

当然,如果我在控制台进行检查或进行单独测试时,这不是结果。

我不了解Rails加载过程,以及它如何以及何时构建ActiveRecord反射,以及何时以及如何可靠地访问它们。有什么见解吗?

1 个答案:

答案 0 :(得分:0)

我找不到任何资源来指导我完成Rails的内部工作,所以我去了一个流行的宝石,同样需要通过ActiveRecord :: Reflections ActiveModel::Serializer解析,因为它也是可能不得不处理Rails没有按照自己的意愿加载东西。在那里,我found

included do
    ...

    extend ActiveSupport::Autoload
    autoload :Association
    autoload :Reflection
    autoload :SingularReflection
    autoload :CollectionReflection
    autoload :BelongsToReflection
    autoload :HasOneReflection
    autoload :HasManyReflection
  end

将此问题添加到我的关注中解决了我的问题。来自ActiveSupport :: Autoload docs:“此模块允许您根据Rails约定定义自动加载(即不需要根据文件名定义自动猜测的路径),还定义了一组需要的常量急切地加载“。