Проверка на рельсах, которая позволяет first_name или last_name быть нулем, но не обоими - PullRequest
0 голосов
/ 11 января 2020
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

я не знаю, что не так в моих строках кода, чтобы получить следующую ошибку от rspe c .. Назначение rq11 Validators: разрешает профиль с нулевым именем, когда присутствует фамилия Ошибка / ошибка: ожидаемо (Profile.new (: first_name => nil,: last_name => «Smith»,: sex => «male»)). to 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? для возврата true, получено false

Файл spe c имеет следующее ..

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

Ответы [ 2 ]

3 голосов
/ 11 января 2020

Хотя ответ Романа правильный, я хотел бы добавить больше деталей и больше опций для решения проблемы.

Ваш Profile belong_to :user. По умолчанию belongs_to ассоциации требуют, чтобы связанный объект существовал. В этом случае должен быть пользователь, связанный с профилем, в противном случае профиль будет недействительным.

У вас есть три варианта решения этой проблемы в зависимости от вашего варианта использования:

  1. Сделайте ассоциацию необязательной, прочитайте о необязательных belongs_to ассоциациях в Rails Guides . Это, очевидно, вариант, только если в контексте вашего приложения имеет смысл, что нет необходимости, чтобы ассоциация существовала всегда.

    belongs_to :user, optional: true
    

    optional: true отключает встроенную проверку.

  2. Вы должны убедиться, что в каждом профиле в вашей записи c всегда есть действительный назначенный пользователь. Примерно так может работать:

    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
    
  3. Вы не только проверяете, является ли экземпляр действительным, но вместо этого, если есть ожидаемое, задаете c error

    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
    
3 голосов
/ 11 января 2020

Я думаю, что это недопустимо, потому что user_id пусто. По умолчанию рельсы проверяют наличие ассоциаций, насколько я помню. Добавьте user_id ко всем профилям, и все должно быть в порядке

...