RSpec FactoryBot Validation не удалось установить отношение многие ко многим - PullRequest
0 голосов
/ 31 мая 2019

Я продолжаю получать ActiveRecord::RecordInvalid: Validation failed: Role must exist при запуске нижеуказанной спецификации.

Я в основном пытаюсь добавить создателей в песню. Сделана кредитная запись, которая является таблицей соединений в базе данных. Теперь в таблице кредитов также есть столбец role_id, который принадлежит таблице ролей. Но я не могу понять, как создать запись о ролях, чтобы она существовала после добавления создателя в песню. Полная разбивка кода ниже.

Spec:

describe '.get' do
        before :each do 
            @song = create(:song)
            @creator = create(:creator)
            @song.creators << @creator    
        end
end

Модель:

class Credit < ApplicationRecord
  belongs_to :song
  belongs_to :creator
  belongs_to :role 
end


class Song < ApplicationRecord
  has_many :credits
  has_many :creators, through: :credits
end



class Creator < ApplicationRecord
    has_many :credits
    has_many :songs, through: :credits
end

class Role < ApplicationRecord
end

Фабрика

FactoryBot.define do 
    factory :song do 
        name { Faker::Music::Phish.song }
        uri {"spotify:track:#{SecureRandom.alphanumeric(22)}"}
        current_popularity {rand(0..100)}
        master {1}
        credits_checked {0}
        credits_verified {0}
        credits_approved {0}
        checked {0}
        created_at {Time.now - rand(3..30).days}
        updated_at {Time.now - 1.days} 
    end
end


FactoryBot.define do 
    factory :creator do 
        name { Faker::Name.name }
        claimed {0}
        created_at {Time.now - rand(10..30).days}
        updated_at {Time.now - rand(1..5).days}
    end
end

FactoryBot.define do
    factory :credit do 
        creator
        song
        role { create(:role) }
        active {1}
        display {1}
        created_at {Time.now - rand(10..30).days}
        updated_at {Time.now - rand(1..5).days}

    end
end

FactoryBot.define do 
    factory :role do 
        name {'Writer'}
        ordering {1}
        created_at {Time.now}
        updated_at {Time.now}
    end
end

1 Ответ

0 голосов
/ 03 июня 2019

Поскольку у вас есть третья belongs_to в модели кредитования, и это требуется, вы не можете использовать способ Rails по умолчанию <<, чтобы добавить связанную запись. У вас есть два варианта здесь:

  1. Сделать связывание ролей необязательным и назначить роль кредиту после создания

    belongs_to :role, optional: true
    
    before :each do 
      @role = create(:role)
      @song = create(:song)
      @creator = create(:creator)
      @song.creators << @creator  
      @song.credits.find_by(creator: @creator).update(role: @role)  
    end
    
  2. Создать кредит явно, без оператора <<

    before :each do 
      @role = create(:role)
      @song = create(:song)
      @creator = create(:creator)
      @song.credits.create(creator: @creator, role: @role)  
    end
    

Я думаю, второй вариант лучше, потому что вы сохраняете валидацию ролей и создаете кредитный экземпляр за одну операцию.

...