Ruby on rails 接受的\u嵌套的\u属性\u并验证生成错误sql请求的\u唯一性\u

Ruby on rails 接受的\u嵌套的\u属性\u并验证生成错误sql请求的\u唯一性\u,ruby-on-rails,validation,rails-activerecord,Ruby On Rails,Validation,Rails Activerecord,我有奇怪的验证请求。这是我的密码: #app/models/user.rb class User < ActiveRecord::Base has_many :exchanges_users, inverse_of: :user end #app/models/exchange.rb class Exchange < ActiveRecord::Base has_many :exchanges_users, inverse_of: :exchange accepts_n

我有奇怪的验证请求。这是我的密码:

#app/models/user.rb
class User < ActiveRecord::Base
  has_many :exchanges_users, inverse_of: :user
end

#app/models/exchange.rb
class Exchange < ActiveRecord::Base
  has_many :exchanges_users, inverse_of: :exchange
  accepts_nested_attributes_for :exchanges_users, :allow_destroy => true, :reject_if => :all_blank
end

#app/models/exchanges_user.rb
class ExchangesUser < ActiveRecord::Base
  validates_presence_of :exchange
  validates_presence_of :user
  validates_uniqueness_of :exchange, :scope => [:user]

  belongs_to :exchange, inverse_of: :exchanges_users
  belongs_to :user, inverse_of: :exchanges_users
end
Rails通过以下请求验证唯一性:

SELECT  1 AS one FROM "exchanges_users" WHERE ("exchanges_users"."exchange_id" IS NULL AND "exchanges_users"."user_id" = 4) LIMIT 1
SELECT  1 AS one FROM "exchanges_users" WHERE ("exchanges_users"."exchange_id" IS NULL AND "exchanges_users"."user_id" = 1) LIMIT 1

显然,“IS NULL”部分是错误的,但我不知道为什么会发生这种情况。你有什么想法吗?

既然你已经验证了:exchange的存在,那么这个查询应该是良性的,但是没有用。您可以通过首先创建
交换
记录并应用其属性来解决此问题

ActiveRecord::Base.transaction do
  e = Exchange.new
  e.save!(validate: false) 
  e.update_attributes({"name"=>"Test", "exchanges_users_attributes"=>{"0"=>{"user_id"=>"4"}, "1"=>{"user_id"=>"1"}}}) 
  e.save!
end

显然,
为空
部分是正确的。您正在验证尚未保存到数据库中的
ExchangeUser
Exchange
,因此它根本没有
id
。你期望它做什么?我简化了这个问题。我的用户模型有一些属性。我需要这3个型号。是,验证在保存exchange之前进行。也许我可以改变这一点?预期的行为是什么?除了
id
之外,还有什么东西使得
交换
唯一吗?
ActiveRecord::Base.transaction do
  e = Exchange.new
  e.save!(validate: false) 
  e.update_attributes({"name"=>"Test", "exchanges_users_attributes"=>{"0"=>{"user_id"=>"4"}, "1"=>{"user_id"=>"1"}}}) 
  e.save!
end