Ruby on rails Rails ActiveRecord关系帮助程序如何允许诸如“user.groups.new”之类的方法?

Ruby on rails Rails ActiveRecord关系帮助程序如何允许诸如“user.groups.new”之类的方法?,ruby-on-rails,ruby-on-rails-3,activerecord,ruby-on-rails-3.2,Ruby On Rails,Ruby On Rails 3,Activerecord,Ruby On Rails 3.2,在Rails中,我创建了一个从LDAP数据库而不是从ActiveRecord检索用户的模型。现在,我试图将ActiveRecord模型与基于LDAP的模型集成,因此我在模型中编写方法,模拟一些常见的ActiveRecord方法 我尝试模仿的方法之一是通常由ActiveRecord上的has_many through关系创建的方法。在ActiveRecord中,此关系将允许以下操作: user = User.first groups = user.groups # == Array of Grou

在Rails中,我创建了一个从LDAP数据库而不是从ActiveRecord检索用户的模型。现在,我试图将ActiveRecord模型与基于LDAP的模型集成,因此我在模型中编写方法,模拟一些常见的ActiveRecord方法

我尝试模仿的方法之一是通常由ActiveRecord上的has_many through关系创建的方法。在ActiveRecord中,此关系将允许以下操作:

user = User.first
groups = user.groups # == Array of Groups
groups << Group.create(name: "Test") # How does Rails allow this?
user=user.first
groups=user.groups#==组数组

groups虽然
user.groups
看起来是一个组数组,但实际上它是一个完全独立的类——一个通常不太了解的Rails内部类,称为关联代理。代理响应类似于
的方法。我将通过查看Rails源代码(例如
上面的Group.create示例可以在中找到


伟大的那正是我要找的。但奇怪的是,在ActiveRecord中调用
user.groups.class
会返回
Array
(而不是其他类)。知道为什么吗?Rails在这里做了一些诡计来实现这一点。在中对其进行了总结,但本质上它称自己为数组,即使实际返回的是AssociationProxy实例(如
ActiveRecord::Associations::HasManyAssociation
)。实现这一点的机制同样复杂,而且似乎主要是这样的:
是一个?(数组)
将以
true
响应。
module LDAP
  class Association
    attr_accessor :source, :target

    def initialize(source, target)
      @source = source
      @target = target
    end

    def <<(obj)
      @source.group_ids = [group_ids + obj].flatten.uniq
      @source.save
    end

  end
end

class User
  def groups
    LDAP::Association.new(self, Group)
  end
end
  def create(attributes = nil, options = {}, &block)
    if attributes.is_a?(Array)
      attributes.collect { |attr| create(attr, options, &block) }
    else
      object = new(attributes, options, &block)
      object.save
      object
    end
  end
end