Mongoid无法使用belongs_to / has_many关系保存文档。循环依赖

时间:2016-09-09 07:43:41

标签: ruby-on-rails ruby mongoid mongoid5

我有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!'

如果没有有效的商家信息,则无法保存预订, 没有有效预订,无法保存列表

这是什么?!?!

请保存我的一天......

1 个答案:

答案 0 :(得分: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

我还将foreign_key替换为inverse_of以获取has_many关系,让Mongoid更容易猜出外键名称:)

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

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