Tôi muốn cải thiện câu trả lời của @luizbranco để làm cho lệnh gọi lại after_save có thể tái sử dụng nhiều hơn khi tạo người dùng khác.
FactoryGirl.define do
factory :user do
first_name "Luiz"
last_name "Branco"
#...
after(:build) { |user|
user.class.skip_callback(:create,
:after,
:run_something1,
:run_something2)
}
trait :with_after_save_callback do
after(:build) { |user|
user.class.set_callback(:create,
:after,
:run_something1,
:run_something2)
}
end
end
end
Chạy mà không có lệnh gọi lại after_save:
FactoryGirl.create(:user)
Chạy với lệnh gọi lại after_save:
FactoryGirl.create(:user, :with_after_save_callback)
Trong thử nghiệm của mình, tôi muốn tạo người dùng không có lệnh gọi lại theo mặc định vì các phương thức được sử dụng chạy thêm những thứ mà tôi thường không muốn trong các ví dụ thử nghiệm của mình.
---------- CẬP NHẬT ------------ Tôi đã ngừng sử dụng jump_callback vì có một số vấn đề không nhất quán trong bộ thử nghiệm.
Giải pháp thay thế 1 (sử dụng phần gốc và phần tách):
after(:build) { |user|
user.class.any_instance.stub(:run_something1)
user.class.any_instance.stub(:run_something2)
}
trait :with_after_save_callback do
after(:build) { |user|
user.class.any_instance.unstub(:run_something1)
user.class.any_instance.unstub(:run_something2)
}
end
Giải pháp thay thế 2 (cách tiếp cận ưa thích của tôi):
after(:build) { |user|
class << user
def run_something1; true; end
def run_something2; true; end
end
}
trait :with_after_save_callback do
after(:build) { |user|
class << user
def run_something1; super; end
def run_something2; super; end
end
}
end
:on => :create
xác thực, hãy sử dụngafter(:build) { |user| user.class.skip_callback(:validate, :create, :after, :run_something) }