Rails ActiveRecord关系助手如何允许诸如`user.groups.new`之类的方法?
在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
。)我缺少什么?
虽然user.groups
看起来是一个组的数组,但它实际上是一个完全独立的类 – 一个Rails内部类,你通常不太了解它叫做关联代理。 代理通过将请求代理到目标类,然后适当地设置关联来响应诸如<<
, create
, new
等方法。
如果您需要类似的function,则必须实现自己的代理关联。 这样做会非常复杂,但这可能会让你开始。
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的解决方案简单得多,应该足以复制一些基本的ActiveRecordfunction。
我会通过窥视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
- 我可以为belongs_to关联添加包含扩展吗?
- Rails ActiveRecord查询日期范围
- 错误:表“用户”上的更新或删除违反表“评论”上的外键约束“fk_rails_03de2dc08c”
- 通过Rails中的belongs_to关系查询记录
- 使用rails嵌套模型来创建*外部对象并同时*编辑*现有的嵌套对象?
- 如何获取ActiveRecordvalidation中配置的最大长度?
- ActiveRecord :: AssociationTypeMismatch:用户期望,得到了Fixnum
- 特别是一对多的关系
- ActiveRecord :: Enum – PG :: InvalidTextRepresentation:ERROR:整数的输入语法无效: