MongoDB MongoMapper更新嵌入式文档(ruby on rails)

时间:2011-11-03 19:23:30

标签: ruby-on-rails ruby mongodb mongomapper

这让我疯了,我觉得我可能错误地使用了嵌入式文档。

class User
    include MongoMapper::Document
    key :name, String
    many :businesses
end

class Business
    include MongoMapper::EmbeddedDocument
    key :name, String
    one :address
    many :clients
    belongs_to :user
end

class Address
    include MongoMapper::EmbeddedDocument
    key :name, String
    belongs_to :business
end

class Client
    include MongoMapper::EmbeddedDocument
    key :name, String
    belongs_to :business
end

我创建了一个用户,然后创建了一个公司,我现在要做的是为业务添加一个地址,但我无法做到。

我唯一能想到的是按名称或ID查找用户,然后遍历业务数组,找到按名称匹配的业务并设置地址......

但老实说这听起来很蹩脚,我认为有一种更优雅的方式。

谢谢

1 个答案:

答案 0 :(得分:0)

首先,当您进行嵌入时,使用embedded_in代替belongs_to

class Business
    include MongoMapper::EmbeddedDocument
    key :name, String
    one :address
    many :clients
    embedded_in :user
end

class Address
    include MongoMapper::EmbeddedDocument
    key :name, String
    embedded_in :business
end

class Client
    include MongoMapper::EmbeddedDocument
    key :name, String
    embedded_in :business
end

原因在于,belongs_to在内部创建了一个复杂的关联代理,为非嵌入式关联执行各种数据库交互,而embedded_in只创建_parent_document的别名方法。 belongs_to仅适用于非嵌入式关联。

没有办法“很好地”查询嵌入式文档。我认为Mongoid允许你假装嵌入式关联就像常规关联一样可查询,但是MongoMapper不喜欢假装。在MongoMapper中,嵌入式文档数组只是Array with very little sugar。 MongoDB最终可能允许嵌入文档的虚拟集合(它是number 1 JIRA issue),我想在那时MM们会考虑更高级的东西。

事实上,Ruby的可枚举方法非常好,而且

user = User.find("1234567abc")

user.business.select { |b| b.name == target_name }.each { |b| b.address = new_address }

user.save