【问题标题】:Mongoid can't save document with a belongs_to/has_many relationship. Circular dependencyMongoid 无法保存具有 belongs_to/has_many 关系的文档。循环依赖
【发布时间】:2016-09-09 07:43:40
【问题描述】:

我有 2 个 Mongoid 类:

class Reservation
  include Mongoid::Document
  belongs_to :listing, class_name: 'Listing', inverse_of: 'Reservation'
end

class Listing
  include Mongoid::Document
  has_many :reservations, class_name: 'Reservation', foreign_key: :listing_id
end

如果我通过_id#save! 找到列表,则不会出现错误

listing = Listing.find(...)
listing.save! #=> true

然后我初始化一个新的预订对象:

reservation = Reservation.find_or_initialize_by(params)
reservation.save! #=> error, exptected though, because I didn't set the listing_id yet

Mongoid::Errors::Validations: 
message:
  Validation of Reservation failed.
summary:
  The following errors were found: Listing can't be blank
resolution:
  Try persisting the document with valid data or remove the validations.
from /home/ec2-user/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/bundler/gems/mongoid-71c29a805990/lib/mongoid/persistable.rb:78:in `fail_due_to_validation!'

所以我将较早的房源的 id 分配给预订:

reservation.listing_id = listing._id
reservation.listing_id #=> nil

我什至不能分配listing_id 字段?!

reservation.listing    #=> returns the associated document no problem though..
reservation.listing.save! #=> error

Mongoid::Errors::Validations: 
message:
  Validation of Listing failed.
summary:
  The following errors were found: Reservations is invalid
resolution:
  Try persisting the document with valid data or remove the validations.
from /home/ec2-user/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/bundler/gems/mongoid-71c29a805990/lib/mongoid/persistable.rb:78:in `fail_due_to_validation!'

如果没有有效的列表,无法保存预订, 没有有效预订,无法保存房源

这是什么?!?!

请拯救我的一天...

【问题讨论】:

    标签: ruby-on-rails ruby mongoid mongoid5


    【解决方案1】:

    您实际上必须在 inverse_of 中指定反向字段,因此请尝试以下内容:

    class Reservation
      include Mongoid::Document
      belongs_to :listing, class_name: 'Listing', inverse_of: :reservations
    end
    
    class Listing
      include Mongoid::Document
      has_many :reservations, class_name: 'Reservation', inverse_of :listing
    end
    

    我还用inverse_of替换了has_many关系的foreign_key,这样更容易让Mongoid猜测外键名:)

    然后,检查您指定的验证并且您没有包含在您的帖子中,但是如果您首先创建一个列表,您应该能够毫无问题地为其创建预订。

    另外,直接分配对象也可以,而且通常更容易,所以你可以直接写reservation.listing = my_listing

    【讨论】:

    • 谢谢!按照您的解决方案,我能够解决我的问题。然而,我确实犯了一个愚蠢的错误,也需要修复。我正在使用 elasticsearch,我定义了一个 #listing_id instance_method 用于索引。这与协会的#listing_id 方法相冲突。虽然能够解决!
    • listing_id由Mongoid自动生成ː)
    猜你喜欢
    • 2015-11-15
    • 2017-09-26
    • 1970-01-01
    • 2014-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多