【问题标题】:MongoDB validation failed from has_and_belongs_to_many relationMongoDB 验证从 has_and_belongs_to_many 关系失败
【发布时间】:2019-11-22 01:19:38
【问题描述】:

我正在构建一个简单的脚本来填充 MongoDB 数据库。这是我第一次使用 NoSQL DB,我觉得我可能是从 SQL DB 的角度考虑这个问题。

此脚本的基础是填充一个数据库,该数据库包含一些相互关联的集合。但是当我运行我的脚本时,我在构建/保存文档时看到了一个无效的错误。

我有三个系列; BookAuthorStyle,具有以下关系。

  • 一个Book 有很多Authors
  • 一个Author有很多Books
  • 一个Author 有很多Styles
  • 一个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 文档已创建,但由于无效的样式验证错误,AuthorStyle 不会持续存在。我希望我能确切地看到导致验证失败的原因,但消息传递非常模糊。我怀疑它来自 AuthorStyle 之间的 has_and_belongs_to_many 关系的一些内置验证,但我无法确定。

我觉得有趣的是Book 文档有一个author_ids 属性,其中填充了id,但是当我跳入控制台时,没有可以拉起或绑定到Book 的作者。

如果需要,很乐意提供更多信息。

【问题讨论】:

    标签: ruby-on-rails ruby mongodb mongoid


    【解决方案1】:

    我想我需要了解更多才能明确告诉您问题所在——您使用的是哪个版本的 Mongoid?您是在空数据库上运行此脚本,还是 Author 和 Style 文档已经存在?那些看起来像什么?

    话虽如此,我确实在您的脚本中看到了一些错误,但我不确定它们是否会导致您的问题:

    1. if style.nil?
            author.styles.build(Style.new(type: style_name))
      else
            ...
      

    我相信 if 语句中的那行会引发错误。相反,它应该说author.styles.build(type: style_name)

    1. unless author.styles.include? style.id
          author.styles << style
      end
      

    unless 之后的表达式总是会计算为 false,因为 author.stylesStyle 对象的数组,而不是样式 ID。相反,它可能应该说author.style_ids.include? style.idauthor.styles.include? style

    如果有帮助,请告诉我!如果您向我提供我要求的额外信息,我很乐意进行更多调试。

    【讨论】:

      猜你喜欢
      • 2016-11-06
      • 2013-11-25
      • 2016-09-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多