在Rails中,我创建了一个模型,用于从LDAP数据库而不是ActiveRecord中检索用户。现在我尝试将我的ActiveRecord模型与基于LDAP的模型集成,因此我在模型中编写模拟一些常见ActiveRecord方法的方法。
我试图模仿的方法之一是通常由ActiveRecord上的has_many关系创建的方法。在ActiveRecord中,这种关系允许以下内容:
user = User.first
groups = user.groups # == Array of Groups
groups << Group.create(name: "Test") # How does Rails allow this?
Rails究竟是如何允许的?我已经尝试动态地将方法分配给user.groups返回的数组实例,但似乎没有任何方法可以让这些方法知道数组是从哪个用户记录创建的。 (所以他们可以在新的关系记录上分配user_id
。)我错过了什么?
答案 0 :(得分:2)
虽然user.groups
似乎是一个组数组,但它实际上是一个完全独立的类 - 一个Rails内部类,你通常不太了解它叫做关联代理。代理通过代理对目标类的请求然后适当地设置关联来响应诸如<<
,create
,new
之类的方法等。
如果您想要类似的功能,则必须实现自己的代理关联。这样做会非常复杂,但这可能会让你开始。
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
这甚至不特别接近ActiveRecord如何实现关联代理。但是,这比ActiveRecord的解决方案简单得多,应该足以复制一些基本的ActiveRecord功能。
答案 1 :(得分:0)
我会通过窥视Rails源代码来做到这一点,例如:的代码 上面的Group.create示例可以在
中找到http://api.rubyonrails.org/classes/ActiveRecord/Persistence/ClassMethods.html
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