And*_*rei 3 version-control ruby-on-rails associations mongodb mongoid
假设用户想要创建一个由其他用户创建的项目组成的集合.项目的Mongoid Document具有版本控制,创建该集合的用户可能不喜欢项目作者对集合项目所做的更改.因此,我希望set文档引用项目的特定版本,允许set author更新项目引用(如果需要).我计划在设置文档中添加一个项目版本号数组,以及一些获取特定版本的设置项目和更新项目版本的方法.你觉得这种方法合理吗?你会如何解决这个问题?
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
Run Code Online (Sandbox Code Playgroud)
我通过在"中间"创建模型来解决这样的问题,例如"ItemReference"MongoDB是文档存储而不是关系数据库,因此在必要时存储重复信息是合法的.MongoDB能够存储嵌入式文档,因此我们将使用这个强大的功能.
ItemReference包含创建视图所需的有关Item的所有重要信息.这减少了视图端的查询,但增加了插入/更新端的查询.
问题是你需要一个由复合主键item_id
和版本号组成的复合主键.
我们来谈谈代码:
物品型号:
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
Run Code Online (Sandbox Code Playgroud)
ItemSet模型
class ItemSet
include Mongoid::Document
field :name, :type => String
embeds_many :item_references
end
Run Code Online (Sandbox Code Playgroud)
ItemReference模型
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
Run Code Online (Sandbox Code Playgroud)
此组合允许您创建包含具有不同版本的项目的集合,并且您可以将集合中的某些ItemReferences更新为特定版本.
这是一个例子:
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
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
459 次 |
最近记录: |