UFO ET IT

FactoryGirl 및 다형성 연관

ufoet 2020. 11. 12. 20:40
반응형

FactoryGirl 및 다형성 연관


디자인

다형성 연결을 통해 프로필에 속하는 사용자 모델이 있습니다. 이 디자인을 선택한 이유는 여기 에서 찾을 수 있습니다 . 요약하면, 정말 다른 프로필을 가진 응용 프로그램 사용자가 많이 있습니다.

class User < ActiveRecord::Base
  belongs_to :profile, :dependent => :destroy, :polymorphic => true
end

class Artist < ActiveRecord::Base
  has_one :user, :as => :profile
end

class Musician < ActiveRecord::Base
  has_one :user, :as => :profile
end

이 디자인을 선택한 후 좋은 테스트를 내리는 데 어려움을 겪고 있습니다. FactoryGirl과 RSpec을 사용하여 가장 효율적인 방법으로 연결을 선언하는 방법을 모르겠습니다.

첫번째 시도

factory.rb

Factory.define :user do |f|
  # ... attributes on the user
  # this creates a dependency on the artist factory
  f.association :profile, :factory => :artist 
end

Factory.define :artist do |a|
  # ... attributes for the artist profile
end

user_spec.rb

it "should destroy a users profile when the user is destroyed" do
  # using the class Artist seems wrong to me, what if I change my factories?
  user = Factory(:user)
  profile = user.profile
  lambda { 
    user.destroy
  }.should change(Artist, :count).by(-1)
end

댓글 / 기타 의견

사용자 사양의 의견에서 언급했듯이 Artist를 사용하는 것은 깨지기 쉽습니다. 내 공장이 나중에 변경되면 어떻게됩니까?

factory_girl 콜백 을 사용하고 "아티스트 사용자"와 "뮤지션 사용자"를 정의 해야 할까요? 모든 입력에 감사드립니다.


Factory_Girl 콜백은 삶을 훨씬 쉽게 만들어 줄 것입니다. 이런 건 어때?

Factory.define :user do |user|
  #attributes for user
end

Factory.define :artist do |artist|
  #attributes for artist
  artist.after_create {|a| Factory(:user, :profile => a)}
end

Factory.define :musician do |musician|
  #attributes for musician
  musician.after_create {|m| Factory(:user, :profile => m)}
end

받아 들여지는 대답이 있지만 여기에 나를 위해 일하고 다른 사람에게 유용 할 수있는 새로운 구문을 사용하는 코드가 있습니다.

spec / factories.rb

FactoryGirl.define do

  factory :musical_user, class: "User" do
    association :profile, factory: :musician
    #attributes for user
  end

  factory :artist_user, class: "User" do
    association :profile, factory: :artist
    #attributes for user
  end

  factory :artist do
    #attributes for artist
  end

  factory :musician do
    #attributes for musician
  end
end

spec / models / artist_spec.rb

before(:each) do
  @artist = FactoryGirl.create(:artist_user)
end

아티스트 인스턴스와 사용자 인스턴스를 생성합니다. 따라서 다음과 같이 전화 할 수 있습니다.

@artist.profile

Artist 인스턴스를 가져옵니다.


이와 같은 특성을 사용하십시오.

FactoryGirl.define do
    factory :user do
        # attributes_for user
        trait :artist do
            association :profile, factory: :artist
        end
        trait :musician do
            association :profile, factory: :musician
        end
    end
end

이제 사용자 인스턴스를 얻을 수 있습니다. FactoryGirl.create(:user, :artist)


중첩 된 팩토리 (상속)를 사용하여이 문제를 해결할 수도 있습니다. 이렇게하면 각 클래스에 대한 기본 팩토리를 만든 다음이 기본 부모에서 상속하는 중첩 팩토리를 만들 수 있습니다.

FactoryGirl.define do
    factory :user do
        # attributes_for user
        factory :artist_profile do
            association :profile, factory: :artist
        end
        factory :musician_profile do
            association :profile, factory: :musician
        end
    end
end

이제 다음과 같이 중첩 된 팩토리에 액세스 할 수 있습니다.

artist_profile = create(:artist_profile)
musician_profile = create(:musician_profile)

이것이 누군가를 돕기를 바랍니다.


공장의 다형성 연관은 일반 Rails 연관과 동일하게 작동하는 것 같습니다.

So there is another less verbose way if you don't care about attributes of model on "belongs_to" association side (User in this example):

# Factories
FactoryGirl.define do
  sequence(:email) { Faker::Internet.email }

  factory :user do
    # you can predefine some user attributes with sequence
    email { generate :email }
  end

  factory :artist do
    # define association according to documentation
    user 
  end
end

# Using in specs    
describe Artist do      
  it 'created from factory' do
    # its more naturally to starts from "main" Artist model
    artist = FactoryGirl.create :artist        
    artist.user.should be_an(User)
  end
end

FactoryGirl associations: https://github.com/thoughtbot/factory_girl/blob/master/GETTING_STARTED.md#associations


I currently use this implementation for dealing with polymorphic associations in FactoryGirl:

In /spec/factories/users.rb:

FactoryGirl.define do

  factory :user do
    # attributes for user
  end

  # define your Artist factory elsewhere
  factory :artist_user, parent: :user do
    profile { create(:artist) }
    profile_type 'Artist'
    # optionally add attributes specific to Artists
  end

  # define your Musician factory elsewhere
  factory :musician_user, parent: :user do
    profile { create(:musician) }
    profile_type 'Musician'
    # optionally add attributes specific to Musicians
  end

end

Then, create the records as usual: FactoryGirl.create(:artist_user)

참고URL : https://stackoverflow.com/questions/7747945/factorygirl-and-polymorphic-associations

반응형