首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Mongoid多对多版本控制

Mongoid多对多版本控制
EN

Stack Overflow用户
提问于 2011-10-15 20:27:08
回答 1查看 466关注 0票数 3

假设一个用户想要创建一个由其他用户创建的项目组成的集合。项目的Mongoid文档有版本控制,创建集合的用户可能不喜欢项目作者对集合中的项目所做的更改。因此,我希望set文档引用项目的特定版本,允许set作者根据需要更新项目引用。我计划在set文档中添加一个项目版本号数组,以及一些获取特定版本的set项目和更新项目版本的方法。你觉得这种方法合理吗?你将如何解决这个问题?

代码语言:javascript
运行
复制
class Item
  include Mongoid::Document
  include Mongoid::Paranoia
  include Mongoid::Versioning
  field :title, type: String
  has_and_belongs_to_many :item_sets
end

class ItemSet
  include Mongoid::Document
  field :name, type: String
  field :item_versions, type: Array
  has_and_belongs_to_many :items
end
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-10-15 21:42:20

我通过在“中间”创建一个模型来解决这类问题,比如"ItemReference“MongoDB是一个文档存储,而不是关系数据库,因此在必要时存储重复信息是合法的。MongoDB具有存储嵌入式文档的能力,所以我们将使用这个很棒的特性。

ItemReference保存创建视图所需的有关项的所有关键信息。这减少了视图端的查询,但增加了插入/更新端的查询。

问题是您需要一个由item_id和版本号组成的“复合主键”。

让我们来谈谈代码:

项目模型:

代码语言:javascript
运行
复制
class Item
  include Mongoid::Document
  include Mongoid::Paranoia
  include Mongoid::Versioning

  field :title, :type => String

  # create a reference
  def to_reference
    # create new reference, containing all crucial attributes for displaying
    ItemReference.new(  
      :item_id => self._parent.nil? ? self.id : self._parent.id,
      :version => self.version, 
      :title => self.title
    )
  end

  # get a certain version of this item
  def get_version(version_number)
    return self if version_number == self.version
    self.versions.where(:version => version_number).first
  end

end

ItemSet模型

代码语言:javascript
运行
复制
class ItemSet
  include Mongoid::Document
  field :name, :type => String

  embeds_many :item_references
end

ItemReference模型

代码语言:javascript
运行
复制
class ItemReference 
  include Mongoid::Document
  embedded_in :item_sets  

  field :title, :type => String

  # this points to the newest version
  belongs_to :item

  # get the original version
  def original
    self.item.get_version(self.version)
  end

  # update this reference to a certain version
  def update_to!(new_version)
    new_version     = self.item.get_version(new_version)
    if new_version.present?
      # copy attribute, except id
      self.attributes = new_version.to_reference.attributes.reject{|(k,v)| k == "_id"} 
      self.save  
    else
      # version not found
      false
    end
  end

  # update to the newest version
  def update_to_head!
    self.update_to!(self.item.version)
  end
end

这种组合允许您创建包含具有不同版本的项目的集合,并且您可以将集合中的某些ItemReferences更新为特定版本。

下面是一个例子:

代码语言:javascript
运行
复制
first         = Item.create(:title => 'Item 1')
first.title   = 'Item 1.1'
first.save

myset         = ItemSet.create(:title => 'My Set')
myset.item_references << first.to_reference
myset.save

first.title   = 'Item 1.2'
first.save

p myset.item_references.first.title # prints Item 1.1
p myset.item_references.first.update_to_head! 
p myset.item_references.first.title # prints Item 1.2
p myset.item_references.first.update_to!(1)
p myset.item_references.first.title # prints Item 1
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7777818

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档