实例化时,belongs_to关联冲突,“验证失败...必须存在”错误

时间:2016-03-16 01:22:05

标签: ruby-on-rails associations belongs-to

这就是我做协会的方式:

class Event < ApplicationRecord
  has_one :lineup
  has_many :artists, :through => :lineup
  belongs_to :venue
end

class Lineup < ApplicationRecord
  belongs_to :artist
  belongs_to :event
end

这就是我试图播种的方式

Event.create!(name: "The Function", 
              date: DateTime.new(2016,2,3,10,0,0,'+7'), 
              venue: Venue.create!(name: "Speakeasy", address: "Lynwood Ave", zip_code: "30312"), 
              lineup: Lineup.create!(:artist => Artist.create!(name: "DJ Sliink", bio: "jersey club king")), 
              description: "free free free")

我得到的错误是ActiveRecord::RecordInvalid: Validation failed: Event must exist,它指向lineup行。如果我设置lineup: nil,则会收到相同的消息,然后在创建Event后尝试执行event1.lineup = Lineup.create!...。我有什么选择摆脱阵容对现有事件的依赖?据我所知,问题在于belongs_to关系,因为如果我从Lineup实例创建中取出artist:,我也会得到Artist must exist错误。

验证:

> Event.validators
 => [#<ActiveRecord::Validations::PresenceValidator:0x007fcaab69fa78 @attributes=[:venue], @options={:message=>:required}>]

> Lineup.validators
 => [#<ActiveRecord::Validations::PresenceValidator:0x007fcaad988238 @attributes=[:artist], @options={:message=>:required}>, #<ActiveRecord::Validations::PresenceValidator:0x007fcaab77c7c0 @attributes=[:event], @options={:message=>:required}>]

在种子文件中没有!,我得到一个完全不同的错误 - ActiveRecord::AssociationTypeMismatch: Venue(#70094220768860) expected, got Fixnum(#70094214808600),但仍然是event = Event.create行。

2 个答案:

答案 0 :(得分:5)

在Rails 5中,belong_to默认为validates_presence_of,因此为了允许不存在的关系,请将optional: true选项添加到belongs_to。例如:

belongs_to :parent,
           optional: true

答案 1 :(得分:1)

为什么要尝试将整个对象保存在另一个对象上?为什么不只是ids?

venue = Venue.create!(name: "Speakeasy", address: "Lynwood Ave", zip_code: "30312")
artist = Artist.create!(name: "DJ Sliink", bio: "jersey club king")
lineup = Lineup.create!(:artist_id => artist.id) 

event = Event.create!(name: "The Function", 
          date: DateTime.new(2016,2,3,10,0,0,'+7'), 
          venue_id: venue.id, 
          lineup_id: lineup.id,
          description: "free free free")

检查您的架构以确保场地和阵容是ID ...如果它们不是,您将它们保存为哪种数据类型?如果他们是字符串,您可以保存名称。您不太可能将整个对象保存到事件中。没有意义。