我正在研究内部工具。以下是我使用的三个主要模型:
Site
has_many Document
has_many Version
文档模型实质上存储了一组内容。我想要做的是使用Version模型设置文档版本。所以版本会存储内容。
现在,我通过嵌套URL创建一个新文档:POST / sites /:id / documents。由于表单存在,并且我没有计划在此更改用户体验,因此我开始构建它以使用Document和Version模型。但是,我开始觉得这是错的。管理子对象的验证并将其推送到父对象变得很痛苦。
另一个注意事项:
Document包含一个名为active_version_id的整数字段。它存储当前是该文档的活动版本的版本。然后我使用该ID获取版本模型,以显示连接到该文档的主要内容。我将其设置为创建文档时创建的版本。
我想做什么
简而言之,这是我期望的工作流程:
这是我的版本模型,因此您可以看到验证逻辑。它基本上检查文档中的标题是否有效(这只是一些标识文本)。并且标题不会在该站点中的任何其他文档的版本中使用:
def document_is_in_valid_format
p = CopyProcess::Processor.new
if !p.contains_valid_headers(self.content)
Rails.logger.debug "Headers invalid."
msg = "Content headers must be in valid format."
self.document.errors[:base] << msg
self.errors[:base] << msg
else
# Check that headers are unique to the parent document
headers = content.split(/\n/)[1..3].join(' - ').gsub(/\/\*|\\\*/,'')
site_documents = []
# get all documents where it's not this one's parent
if self.id
site_documents = Document.where(["site_id = ? AND id <> ?", self.site_id, self.document_id])
else
site_documents = Document.where(["site_id = ?", self.site_id])
end
site_documents.includes(:versions)
site_documents.each do |doc|
if doc.version_names.include?(headers)
msg = "Content headers are not unique."
self.document.errors[:base] << msg
self.errors[:base] << msg
break
end
end
end
end
我想知道这里的解决方案是否可以使用嵌套表单。对于第5步,我认为交易有助于防止两次保存。
答案 0 :(得分:2)
我建议您改用the PaperTrail gem,而不是滚动自己的版本控制系统。然后,您可以放弃Version
模型,并为您只需要的Document
模型添加版本控制:
class Document < ActiveRecord::Base
has_paper_trail
# ...
end
你完成了!宝石有很好的记录,所以一定要先检查一下。
答案 1 :(得分:1)
登入http://api.rubyonrails.org查询:
另请注意,您可以在_id / _ids字段上使用验证,例如validates :document_ids, presence: true
,以确保至少有一个文档。
为了使代码更具可读性,我会尝试使用以下方法在自定义验证器中拆分长验证序列: