Ruby on rails 如何测试关联上属性的唯一性

Ruby on rails 如何测试关联上属性的唯一性,ruby-on-rails,rspec,Ruby On Rails,Rspec,鉴于一个用户可以有多个地址,我试图验证一个给定的用户对于一个给定的地址类型只能有一个地址。例如,用户可以有一个主地址和一个账单地址,但用户不能有两个主地址。我如何在我的模型上实施该规则,以及如何对其进行测试?我目前最好的猜测是,我需要验证作用域为user\u id的address\u类型的唯一性,但这段代码阻止相同类型的两个地址存在。我见过其他人编写与此非常类似的代码,但检查字符串而不是枚举 <!-- language: lang-ruby --> # user.rb class U

鉴于一个用户可以有多个地址,我试图验证一个给定的用户对于一个给定的地址类型只能有一个地址。例如,用户可以有一个主地址和一个账单地址,但用户不能有两个主地址。我如何在我的模型上实施该规则,以及如何对其进行测试?我目前最好的猜测是,我需要验证作用域为user\u id的address\u类型的唯一性,但这段代码阻止相同类型的两个地址存在。我见过其他人编写与此非常类似的代码,但检查字符串而不是枚举

<!-- language: lang-ruby -->
# user.rb
class User < ApplicationRecord
  has_many :addresses
end

# address.rb
class Address < ApplicationRecord
  belongs_to :user
  enum :address_type => { :primary, :mailing, :billing }
  validates :address_type, :uniqueness => { :scope => :user_id }
end

Rails唯一性验证可以很好地处理整型列。但是,您的枚举定义不是有效的Ruby语法

class Address < ApplicationRecord
  belongs_to :user
  enum :address_type => [ :primary, :mailing, :billing ]
  # or preferably with Ruby 2.0+ hash syntax
   enum address_type: [ :primary, :mailing, :billing ]
  # ...
end
注意不要只是测试expectduplicate.valid?。是否为falsy和expectduplicate.valid?因为它可能导致误报/否定。而是测试特定的错误消息或密钥。对于这个目的来说是很好的,但不是绝对必要的

require 'rails_helper'

RSpec.describe Address, type: :model do
  # shoulda-matchers takes care of the boilerplate
  it { should validate_uniqueness_of(:address_type).scoped_to(:user_id) }
end

您还应该考虑在AddiSers.AddiStSype和Advest.UsSeriID上添加一个复合唯一索引,因为这将防止。

乍一看这是正确的。您能否共享唯一性SQL查询的日志?您的地址模型包含语法错误。枚举声明应为枚举地址类型:[:主、:邮寄、:账单]。只有在声明密钥/值的散列时才允许使用括号枚举地址类型:{1=>:primary,2=>:mailing,3=>:billing}。谢谢!我更新了我的枚举以使用正确的哈希语法,并且能够通过测试。但是,我尝试使用Shoulda匹配器,结果发现ArgumentError:“任意值”不是有效的地址类型。我遗漏了什么吗?你可以试着像这个问题那样明确地设置主题
require 'rails_helper'

RSpec.describe Address, type: :model do
  # shoulda-matchers takes care of the boilerplate
  it { should validate_uniqueness_of(:address_type).scoped_to(:user_id) }
end