对 rails 的验证允许 first_name 或 last_name 为空但不能同时为空
Validation on rails that permits first_name or last_name to be null but not both
class Profile < ApplicationRecord
belongs_to :user
validate :first_or_last_name_null
def first_or_last_name_null
if first_name.nil? && last_name.nil?
errors.add(:base, "either first_name or last_name must be present!")
end
end
我不知道从 rspec.. 得到以下错误的代码行有什么问题
分配 rq11 验证器:当姓氏出现时允许配置文件的名字为空
Failure/Error:期望(Profile.new(:first_name=>无,:last_name=>"Smith",:性别=>"male"))。至 be_valid
预期 #<Profile id: nil, gender: "male", birth_year: nil, first_name: nil, last_name: "Smith", user_id: nil, created_at: nil, updated_at: nil>.valid?
到 return 为真,结果为假
规范文件具有以下内容..
context "rq11" do
context "Validators:" do
it "does not allow a User without a username" do
expect(User.new(:username=> "")).to_not be_valid
end
it "does not allow a Profile with a null first and last name" do
expect(Profile.new(:first_name=>nil, :last_name=>nil, :gender=>"male")).to_not be_valid
end
it "allows a Profile with a null first name when last name present" do
expect(Profile.new(:first_name=>nil, :last_name=>"Smith", :gender=>"male")).to be_valid
end
it "allows a Profile with a null last name when first name present" do
expect(Profile.new(:first_name=>"Joe", :last_name=>nil, :gender=>"male")).to be_valid
end
it "does not allow a Profile with a gender other than male or female " do
expect(Profile.new(:first_name=>"first", :last_name=>"last", :gender=>"neutral")).to_not be_valid
end
it "does not allow a boy named Sue" do
expect(Profile.new(:first_name=>"Sue", :last_name=>"last", :gender=>"male")).to_not be_valid
end
it "allows a Profile with gender male" do
expect(Profile.new(:first_name=>"first", :last_name=>"last", :gender=>"male")).to be_valid
end
it "allows a Profile with gender female" do
expect(Profile.new(:first_name=>"first", :last_name=>"last", :gender=>"female")).to be_valid
end
end
end
我认为它无效,因为 user_id
是空的。默认情况下 rails 验证关联的存在,我记得。将user_id
添加到所有配置文件,应该没问题
虽然 Roman 的回答是正确的,但我想添加更多细节和更多选项来解决问题。
你的 Profile
belong_to :user
。默认情况下 belongs_to
关联要求关联对象存在。在这种情况下,必须有一个用户与配置文件相关联,否则配置文件将无效。
根据您的用例,您可以选择三个选项来解决此问题:
使关联可选,阅读 optional belongs_to
associations in the Rails Guides。这显然只是一个选项,如果它在您的应用程序上下文中有意义,即不需要始终存在关联。
belongs_to :user, optional: true
optional: true
禁用内置验证。
您确保规范中的每个配置文件始终分配有有效用户。这样的事情可能会奏效:
let(:user) { User.find_or_create_by(username: 'test_user') }
it "does not allow a Profile with a null first and last name" do
expect(Profile.new(user: user, first_name: nil, last_name: nil, gender: "male")).to_not be_valid
end
您不仅要测试实例是否有效,还要测试是否存在预期的特定错误
it "does not allow a Profile with a null first and last name" do
profile = Profile.new(:first_name=>nil, :last_name=>nil, :gender=>"male")
profile.valid? # trigger validations
# with all Rails versions
expect(profile.errors[:base]).to include "either first_name or last_name must be present!"
# or with Rails >= 6:
expect(profile.errors).to be_of_kind(:base, "either first_name or last_name must be present!")
end
class Profile < ApplicationRecord
belongs_to :user
validate :first_or_last_name_null
def first_or_last_name_null
if first_name.nil? && last_name.nil?
errors.add(:base, "either first_name or last_name must be present!")
end
end
我不知道从 rspec.. 得到以下错误的代码行有什么问题
分配 rq11 验证器:当姓氏出现时允许配置文件的名字为空
Failure/Error:期望(Profile.new(:first_name=>无,:last_name=>"Smith",:性别=>"male"))。至 be_valid
预期 #<Profile id: nil, gender: "male", birth_year: nil, first_name: nil, last_name: "Smith", user_id: nil, created_at: nil, updated_at: nil>.valid?
到 return 为真,结果为假
规范文件具有以下内容..
context "rq11" do
context "Validators:" do
it "does not allow a User without a username" do
expect(User.new(:username=> "")).to_not be_valid
end
it "does not allow a Profile with a null first and last name" do
expect(Profile.new(:first_name=>nil, :last_name=>nil, :gender=>"male")).to_not be_valid
end
it "allows a Profile with a null first name when last name present" do
expect(Profile.new(:first_name=>nil, :last_name=>"Smith", :gender=>"male")).to be_valid
end
it "allows a Profile with a null last name when first name present" do
expect(Profile.new(:first_name=>"Joe", :last_name=>nil, :gender=>"male")).to be_valid
end
it "does not allow a Profile with a gender other than male or female " do
expect(Profile.new(:first_name=>"first", :last_name=>"last", :gender=>"neutral")).to_not be_valid
end
it "does not allow a boy named Sue" do
expect(Profile.new(:first_name=>"Sue", :last_name=>"last", :gender=>"male")).to_not be_valid
end
it "allows a Profile with gender male" do
expect(Profile.new(:first_name=>"first", :last_name=>"last", :gender=>"male")).to be_valid
end
it "allows a Profile with gender female" do
expect(Profile.new(:first_name=>"first", :last_name=>"last", :gender=>"female")).to be_valid
end
end
end
我认为它无效,因为 user_id
是空的。默认情况下 rails 验证关联的存在,我记得。将user_id
添加到所有配置文件,应该没问题
虽然 Roman 的回答是正确的,但我想添加更多细节和更多选项来解决问题。
你的 Profile
belong_to :user
。默认情况下 belongs_to
关联要求关联对象存在。在这种情况下,必须有一个用户与配置文件相关联,否则配置文件将无效。
根据您的用例,您可以选择三个选项来解决此问题:
使关联可选,阅读 optional
belongs_to
associations in the Rails Guides。这显然只是一个选项,如果它在您的应用程序上下文中有意义,即不需要始终存在关联。belongs_to :user, optional: true
optional: true
禁用内置验证。您确保规范中的每个配置文件始终分配有有效用户。这样的事情可能会奏效:
let(:user) { User.find_or_create_by(username: 'test_user') } it "does not allow a Profile with a null first and last name" do expect(Profile.new(user: user, first_name: nil, last_name: nil, gender: "male")).to_not be_valid end
您不仅要测试实例是否有效,还要测试是否存在预期的特定错误
it "does not allow a Profile with a null first and last name" do profile = Profile.new(:first_name=>nil, :last_name=>nil, :gender=>"male") profile.valid? # trigger validations # with all Rails versions expect(profile.errors[:base]).to include "either first_name or last_name must be present!" # or with Rails >= 6: expect(profile.errors).to be_of_kind(:base, "either first_name or last_name must be present!") end