RoR과 함께 FactoryGirl 3.3.0을 사용 중입니다. 3.2.3FactoryGirl 콜백이 실행되지 않아야하는 이유는 무엇입니까?
프로필이 has_one 인 사용자 모델이 있습니다. 그래서 프로필이없는 사용자를 가질 수 있습니다 실행 build_profile : 내 RSpec에 테스트에서
class User < ActiveRecord::Base
has_secure_password
has_one :profile, dependent: :destroy
accepts_nested_attributes_for :profile, update_only: true
attr_accessible :email, :username, :password, :password_confirmation, :profile_attributes
before_create :build_profile
end
class Profile < ActiveRecord::Base
attr_accessible :first_name, :last_name
belongs_to :user
validates :user, presence: true
validates :first_name, presence: true, on: :update
validates :last_name, presence: true, on: :update
end
나는 때때로 before_create을 방지 할 필요가있다. FactoryGirl 콜백으로이 문제를 해결합니다.
after(:build) {|user| user.class.skip_callback(:create, :before, :build_profile)}
내 사용자 공장은 다음과 같이 정의됩니다.
FactoryGirl.define do
factory :user do
sequence(:email) {|n| "user_#{n}@example.com"}
sequence(:username) {|n| "user_#{n}"}
password "secret"
factory :user_with_profile do
factory :new_user_with_profile do
before(:create) {|user| user.activated = false}
end
factory :activated_user_with_profile do
before(:create) {|user| user.activated = true}
end
end
factory :user_without_profile do
after(:build) {|user| user.class.skip_callback(:create, :before, :build_profile)}
factory :new_user_without_profile do
before(:create) {|user| user.activated = false}
end
factory :activated_user_without_profile do
before(:create) {|user| user.activated = true}
end
end
end
end
내 기대는 :new_user_without_profile
및 :activated_user_without_profile
는 동안 :new_user_with_profile
및 :activated_user_with_profile
공장 않을 것 :user_without_profile
에서 after(:build)
콜백을 상속 할 것이라고했지만, 꽤 그런 식으로 작동하지 않습니다. 여기 내 문제를 설명하기 위해 콘솔에서 발췌 한 내용이 있습니다.
irb(main):001:0> user = FactoryGirl.create :new_user_with_profile
irb(main):002:0> user.profile
=> #<Profile id: 11, first_name: "", last_name: "", created_at: "2012-07-10 08:40:10", updated_at: "2012-07-10 08:40:10", user_id: 18>
irb(main):003:0> user = FactoryGirl.create :new_user_without_profile
irb(main):004:0> user.profile
=> nil
irb(main):005:0> user = FactoryGirl.create :new_user_with_profile
irb(main):006:0> user.profile
=> nil
그래서, 내가 만들 처음 예상대로 new_user_with_profile는 프로필이 생성되지만 (A 만든 후 : new_user_without_profile를) 두 번째로, 그것은 더 이상하지 않습니다! after (: build) 콜백은 다시 호출되지 않는 것처럼 보입니다. (뭔가 코드를 출력하면 터미널에 표시되지 않습니다.) 나는 여기서 무엇이 잘못 될지 전혀 모른다. 다른 사람 있습니까?
아니요. 시도하지 않았지만 제대로 작동했습니다. 고마워, 적어도 내 테스트가 작동합니다. 그것은 실제로 더러운 해결책입니다 - 나는 실제로 잘못되고있는 것이 무엇인지 이해하기를 원합니다. – brad
여기서 일어나는 일은 정말 간단합니다. 당신의'user.class.skip_callback (: create, : before, : build_profile)'선언을 보시오. 콜백은 클래스의 인스턴스가 아니라 클래스에 설정되기 때문에, 처음에'FactoryGirl.create : new_user_without_profile'을 호출하면 콜백을 건너 뛰도록 설정됩니다. 나중에 'FactoryGirl.create : new_user_with_profile'을 호출하면 이전에 삭제했기 때문에 자연스럽게 콜백이 설정되지 않습니다. 내 제안은 다시 설정하는 것입니다. – Gerry
미안하지만 저를 위해 작동하지 않습니다. –