Factory_bot ActiveRecord :: RecordInvalid - PullRequest
0 голосов
/ 06 марта 2019

Не могу понять, из-за чего произошла эта ошибка, поэтому мой заголовок такой неловкий.Во всех моих спецификациях возникает ошибка ActiveRecord :: RecordInvalid в случайном порядке (один тест повышает, следующий - нет).Вот ссылка на репо https://github.com/artemaminov/frenchesna

Модель собаки

class Dog < ApplicationRecord
  belongs_to :mother, class_name: 'Dog', foreign_key: 'mother_id', optional: true
  belongs_to :father, class_name: 'Dog', foreign_key: 'father_id', optional: true
  has_many :kids, class_name: 'Dog'

  has_many :pictures, class_name: "Image", inverse_of: :dog
  belongs_to :avatar, class_name: "Image", optional: true
  belongs_to :background, class_name: "Image", optional: true

  accepts_nested_attributes_for :pictures, :kids, allow_destroy: true

  # scope :background, -> { joins(:pictures).where(background: true) }

  enum gender: { male: 1, female: 0 }

  validates :name, :nickname, :birthdate, :gender, :award_point, :about, :rip, presence: true
end

Изображение модели

class Image < ApplicationRecord
  belongs_to :dog, inverse_of: :pictures

  has_one_attached :file
end

Фабрика собаки

FactoryBot.define do

  factory :dog do
    name { Faker::Name.name_with_middle }
    nickname { Faker::Name.first_name }
    birthdate { Faker::Date.birthday(1, 10) }
    about { Faker::Lorem.paragraph(2) }
    award_point { Faker::Number.between(1, 5) }
    rip { Faker::Boolean.boolean }
    gender { Faker::Number.between(0, 1) }

    trait :with_pictures_uploaded do
      transient {
        images_count { 1 }
      }

      after(:create) do |dog, evaluator|
        build_list(:image, evaluator.images_count, dog: dog) do #Why order is empty
          file_path = Rails.root.join('spec', 'support', 'assets', 'dog-thumb.jpg')
          file = fixture_file_upload(file_path, 'image/jpg')
          # byebug
          dog.pictures.create.file.attach(file)
        end
      end

    end

  end
end

Фабрика изображения

FactoryBot.define do
  factory :image do
    dog
    order { Faker::Number.between(0, 10) }
  end
end

Спецификация собаки

require 'rails_helper'

RSpec.describe Dog, type: :model do
  subject { create(:dog) }
  let(:dog_with_pictures) { create(:dog, :with_pictures_uploaded, images_count: 1) }

  context 'when added' do
    it { is_expected.to validate_presence_of :nickname }
    it { is_expected.to validate_presence_of :name }
    it { is_expected.to validate_presence_of :birthdate }
    it { is_expected.to validate_presence_of :about }
    it { is_expected.to validate_presence_of :award_point }
    it { is_expected.to validate_presence_of :rip }
    it { is_expected.to define_enum_for(:gender) }
    it 'includes pictures' do
      byebug
      mydog = dog_with_pictures
      expect(mydog.pictures.count).to eq(1)
    end
  end

end

test.log

 [1m[35m (0.5ms)[0m  [1m[34mSELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC[0m
[1m[35m (0.1ms)[0m  [1m[36mbegin transaction[0m
[1m[35m (0.1ms)[0m  [1m[35mSAVEPOINT active_record_1[0m
[1m[35m (0.1ms)[0m  [1m[31mROLLBACK TO SAVEPOINT active_record_1[0m
[1m[35m (0.1ms)[0m  [1m[31mrollback transaction[0m
[1m[35m (0.1ms)[0m  [1m[36mbegin transaction[0m
[1m[35m (0.1ms)[0m  [1m[35mSAVEPOINT active_record_1[0m
[1m[35m (0.1ms)[0m  [1m[31mROLLBACK TO SAVEPOINT active_record_1[0m
[1m[35m (0.0ms)[0m  [1m[31mrollback transaction[0m
[1m[35m (0.0ms)[0m  [1m[36mbegin transaction[0m
[1m[35m (0.1ms)[0m  [1m[35mSAVEPOINT active_record_1[0m
[1m[36mDog Create (3.0ms)[0m  [1m[32mINSERT INTO "dogs" ("name", "nickname", "birthdate", "about", "award_point", "rip") VALUES (?, ?, ?, ?, ?, ?)[0m  [["name", "Анатолий Савина Казакова"], ["nickname", "Евгений"], ["birthdate", "2015-10-27"], ["about", "Ipsam necessitatibus fugiat. Ex occaecati vitae."], ["award_point", 2], ["rip", 1]]
[1m[35m (0.1ms)[0m  [1m[35mRELEASE SAVEPOINT active_record_1[0m
[1m[35m (0.4ms)[0m  [1m[31mrollback transaction[0m
[1m[35m (0.0ms)[0m  [1m[36mbegin transaction[0m
[1m[35m (0.1ms)[0m  [1m[35mSAVEPOINT active_record_1[0m
[1m[36mDog Create (0.5ms)[0m  [1m[32mINSERT INTO "dogs" ("name", "nickname", "birthdate", "about", "gender", "award_point", "rip") VALUES (?, ?, ?, ?, ?, ?, ?)[0m  [["name", "Фёдор Сысоев Семенова"], ["nickname", "Виталий"], ["birthdate", "2017-07-22"], ["about", "Et rerum quia. Dignissimos distinctio consequatur."], ["gender", 1], ["award_point", 4], ["rip", 1]]
[1m[35m (0.1ms)[0m  [1m[35mRELEASE SAVEPOINT active_record_1[0m
[1m[35m (0.7ms)[0m  [1m[31mrollback transaction[0m
[1m[35m (0.1ms)[0m  [1m[36mbegin transaction[0m
[1m[35m (0.1ms)[0m  [1m[35mSAVEPOINT active_record_1[0m
[1m[35m (0.1ms)[0m  [1m[31mROLLBACK TO SAVEPOINT active_record_1[0m
[1m[35m (0.0ms)[0m  [1m[31mrollback transaction[0m
[1m[35m (0.1ms)[0m  [1m[36mbegin transaction[0m
[1m[35m (0.1ms)[0m  [1m[35mSAVEPOINT active_record_1[0m
[1m[35m (0.1ms)[0m  [1m[31mROLLBACK TO SAVEPOINT active_record_1[0m
[1m[35m (0.0ms)[0m  [1m[31mrollback transaction[0m
[1m[35m (0.1ms)[0m  [1m[36mbegin transaction[0m
[1m[35m (0.1ms)[0m  [1m[35mSAVEPOINT active_record_1[0m
[1m[36mDog Create (0.5ms)[0m  [1m[32mINSERT INTO "dogs" ("name", "nickname", "birthdate", "about", "award_point", "rip") VALUES (?, ?, ?, ?, ?, ?)[0m  [["name", "Алла Ершов Брагина"], ["nickname", "Анастасия"], ["birthdate", "2015-09-02"], ["about", "Expedita corrupti aut. Iste autem molestiae."], ["award_point", 1], ["rip", 1]]
[1m[35m (0.0ms)[0m  [1m[35mRELEASE SAVEPOINT active_record_1[0m
[1m[35m (0.5ms)[0m  [1m[31mrollback transaction[0m
[1m[35m (0.0ms)[0m  [1m[36mbegin transaction[0m
[1m[35m (0.1ms)[0m  [1m[35mSAVEPOINT active_record_1[0m
[1m[35m (0.0ms)[0m  [1m[31mROLLBACK TO SAVEPOINT active_record_1[0m
[1m[35m (0.0ms)[0m  [1m[31mrollback transaction[0m

ОБНОВЛЕНИЕ 1 Сокращенный код только для Собаки.То же самое

Модель собаки

class Dog < ApplicationRecord
  validates :name, :nickname, :birthdate, :gender, :award_point, :about, :rip, presence: true
end

Собачья фабрика

FactoryBot.define do
  factory :dog do
    name { Faker::Name.name_with_middle }
    nickname { Faker::Name.first_name }
    birthdate { Faker::Date.birthday(1, 10) }
    about { Faker::Lorem.paragraph(2) }
    award_point { Faker::Number.between(1, 5) }
    rip { Faker::Boolean.boolean }
    gender { Faker::Number.between(0, 1) }
  end
end

Спецификация собаки

require 'rails_helper'

RSpec.describe Dog, type: :model do
  subject { create(:dog) }
  context 'when added' do
    it { is_expected.to validate_presence_of :nickname }
    it { is_expected.to validate_presence_of :name }
    it { is_expected.to validate_presence_of :birthdate }
    it { is_expected.to validate_presence_of :about }
    it { is_expected.to validate_presence_of :award_point }
    it { is_expected.to validate_presence_of :rip }
  end

end

test.log

  [1m[35m (0.6ms)[0m  [1m[34mSELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC[0m
  [1m[35m (0.1ms)[0m  [1m[36mbegin transaction[0m
  [1m[35m (0.1ms)[0m  [1m[35mSAVEPOINT active_record_1[0m
  [1m[35m (0.1ms)[0m  [1m[31mROLLBACK TO SAVEPOINT active_record_1[0m
  [1m[35m (0.0ms)[0m  [1m[31mrollback transaction[0m
  [1m[35m (0.1ms)[0m  [1m[36mbegin transaction[0m
  [1m[35m (0.1ms)[0m  [1m[35mSAVEPOINT active_record_1[0m
  [1m[36mDog Create (0.7ms)[0m  [1m[32mINSERT INTO "dogs" ("name", "nickname", "birthdate", "about", "gender", "award_point", "rip") VALUES (?, ?, ?, ?, ?, ?, ?)[0m  [["name", "Юлия Фомичева Денисова"], ["nickname", "Станислав"], ["birthdate", "2013-03-14"], ["about", "Est dicta aut. Aut ea sequi."], ["gender", 0], ["award_point", 2], ["rip", 1]]
  [1m[35m (0.1ms)[0m  [1m[35mRELEASE SAVEPOINT active_record_1[0m
  [1m[35m (0.4ms)[0m  [1m[31mrollback transaction[0m
  [1m[35m (0.1ms)[0m  [1m[36mbegin transaction[0m
  [1m[35m (0.1ms)[0m  [1m[35mSAVEPOINT active_record_1[0m
  [1m[35m (0.1ms)[0m  [1m[31mROLLBACK TO SAVEPOINT active_record_1[0m
  [1m[35m (0.0ms)[0m  [1m[31mrollback transaction[0m
  [1m[35m (0.1ms)[0m  [1m[36mbegin transaction[0m
  [1m[35m (0.1ms)[0m  [1m[35mSAVEPOINT active_record_1[0m
  [1m[35m (0.1ms)[0m  [1m[31mROLLBACK TO SAVEPOINT active_record_1[0m
  [1m[35m (0.0ms)[0m  [1m[31mrollback transaction[0m
  [1m[35m (0.1ms)[0m  [1m[36mbegin transaction[0m
  [1m[35m (0.1ms)[0m  [1m[35mSAVEPOINT active_record_1[0m
  [1m[35m (0.1ms)[0m  [1m[31mROLLBACK TO SAVEPOINT active_record_1[0m
  [1m[35m (0.0ms)[0m  [1m[31mrollback transaction[0m
  [1m[35m (0.1ms)[0m  [1m[36mbegin transaction[0m
  [1m[35m (0.1ms)[0m  [1m[35mSAVEPOINT active_record_1[0m
  [1m[36mDog Create (0.4ms)[0m  [1m[32mINSERT INTO "dogs" ("name", "nickname", "birthdate", "about", "gender", "award_point", "rip") VALUES (?, ?, ?, ?, ?, ?, ?)[0m  [["name", "Игнатий Емельянова Рыбаков"], ["nickname", "Денис"], ["birthdate", "2017-02-25"], ["about", "In autem et. Rerum et suscipit."], ["gender", 0], ["award_point", 5], ["rip", 1]]
  [1m[35m (0.0ms)[0m  [1m[35mRELEASE SAVEPOINT active_record_1[0m
  [1m[35m (0.4ms)[0m  [1m[31mrollback transaction[0m

Неудачные примеры

rspec ./spec/models/dog_spec.rb:8 # Dog when added
rspec ./spec/models/dog_spec.rb:10 # Dog when added
rspec ./spec/models/dog_spec.rb:11 # Dog when added
rspec ./spec/models/dog_spec.rb:12 # Dog when added

Schema.rb

ActiveRecord::Schema.define(version: 2019_03_01_092839) do
  create_table "dogs", force: :cascade do |t|
    t.string "name"
    t.string "nickname"
    t.date "birthdate"
    t.text "about"
    t.integer "gender", default: 0
    t.integer "award_point"
    t.boolean "rip"
  end
end

Ответы [ 2 ]

0 голосов
/ 06 марта 2019

решаемая. Проблема была с логическими и перечислимыми валидаторами. Вот что решило проблему

модель собаки

Before
validates :name, :nickname, :birthdate, :gender, :award_point, :about, :rip, presence: true

After
validates_presence_of :name, :nickname, :birthdate, :award_point, :about
validates_inclusion_of :gender, in: %w(male female)
validates_inclusion_of :rip, in: [true, false]

Спекуляция собаки

Before
it { is_expected.to validate_presence_of :rip }
it { is_expected.to define_enum_for(:gender) }

After
it { is_expected.to validate_inclusion_of(:rip).in_array([true, false]) }
it { is_expected.to define_enum_for(:gender).with_values(male: 1, female: 0) }
0 голосов
/ 06 марта 2019

По-моему, вам нужно использовать has_one вместо belongs_to.Итак, замените этот

belongs_to :avatar, class_name: "Image", optional: true

следующим -

has_one :avatar, class_name: "Image"

update Это также относится к фоновой ассоциации.

Опишите свою базу данныхздесь - https://www.dbdesigner.net/ для лучшего понимания.

...