ruby-on-rails - MongoDB 验证从 has_and_belongs_to_many 关系失败
问题描述
我正在构建一个简单的脚本来填充 MongoDB 数据库。这是我第一次使用 NoSQL DB,我觉得我可能是从 SQL DB 的角度考虑这个问题。
该脚本的基础是填充一个数据库,该数据库包含一些相互关联的集合。但是当我运行我的脚本时,我在构建/保存文档时看到了一个无效的错误。
我有三个系列;Book
, Author
, 和Style
, 具有以下关系。
- A
Book
有很多Authors
- 一个
Author
有很多Books
- 一个
Author
有很多Styles
- A
Style
有很多Authors
模型定义如下:
# Book Model
class Book
include Mongoid::Document
include Mongoid::Timestamps
field :title, type: String
validates :title, presence: true
has_and_belongs_to_many :authors
index({ title: 'text' })
end
# Author Model
class Author
include Mongoid::Document
include Mongoid::Timestamps
field :name, type: String
validates :name, presence: true
has_and_belongs_to_many :books
has_and_belongs_to_many :styles
index({ name: 1 }, { unique: true })
end
# Style Model
class Style
include Mongoid::Document
include Mongoid::Timestamps
field :type, type: String
validates :type, presence: true
has_and_belongs_to_many :authors
index({ type: 1 }, { unique: true, name: "type_index" })
end
然后这是我的脚本:
# script.rb
book = Book.new
book.title = "Good Omens"
['Neil Gaiman', 'Terry Pratchett'].each do |author_name|
author = Author.find_by(name: author_name)
if author.nil?
author = Author.new(name: author_name)
end
# a list of writing styles this author can have
# pretend that there's a list of styles per author
literary_styles.each do |style_name|
style = Style.find_by(type: style_name)
if style.nil?
author.styles.build(Style.new(type: style_name))
else
unless author.styles.include? style.id
author.styles << style
end
end
end
author.valid? #=> false
author.errors #=> @messages={:styles=>["is invalid"]}
book.author.build(book.attributes)
book.save
end
Book
文档已创建,但由于无效Author
的样式验证错误而Style
不会持续存在。我希望我能确切地看到导致验证失败的原因,但消息传递非常模糊。我怀疑它来自和has_and_belongs_to_many
之间关系的一些内置验证Author
,Style
但我无法确定它。
我发现有趣的是,该Book
文档有一个author_ids
填充了 id 的属性,但是当我跳入控制台时,没有可以拉起或绑定到Book
.
如果需要,很乐意提供更多信息。
解决方案
我想我需要了解更多才能明确告诉您问题所在——您使用的是什么版本的 Mongoid?您是在空数据库上运行此脚本,还是已经存在 Author 和 Style 文档?那些看起来像什么?
话虽如此,我确实在您的脚本中看到了一些错误,但我不确定它们是否会导致您的问题:
if style.nil? author.styles.build(Style.new(type: style_name)) else ...
我相信 if 语句中的行会引发错误。相反,它应该说author.styles.build(type: style_name)
.
unless author.styles.include? style.id author.styles << style end
after 的表达式unless
总是会计算为 false,因为author.styles
它是一个对象数组Style
,而不是样式 ID。相反,它可能应该说author.style_ids.include? style.id
或author.styles.include? style
让我知道这是否有帮助!如果您向我提供我要求的额外信息,我很乐意进行更多调试。
推荐阅读
- visual-studio-code - Visual Studio Code 静默不连接到市场
- excel - 计划:遍历日期行,复制具有相应标题的列中的非空白
- cuda - 将 jpeg 图像内容作为 CUDA 纹理传递
- c# - ASP.NET Core 验证:动态关闭某些属性的服务器验证
- mysql - 如何检查两个用户是否有共同的聊天室?
- javascript - 如何使用 laravel 将 id 值从另一个表插入到表中
- c# - 如何允许 .NET Core Web 应用访问网络驱动器?
- php - Symfony 5,Doctrine - 插入“杂项”脚本的最佳实践
- python - Pygame 中的记忆游戏
- rgb - 如何将 3D 边界框从点云转换为 ROS 中匹配的 RGB 帧?