Use instance_exec passing self as an argument for dynamic attributes

Calling `block.call(self)` means any implied scope of block evaluation
goes out the window when an arity of 1 is used. This change uses
`instance_exec`, passing along self as the argument for the block
variable, meaning that the block is still invoked within the context of
the FactoryGirl::Evaluator while allowing the variable to have access to
the evaluator.

Closes #529
This commit is contained in:
Joshua Clayton 2013-06-07 10:42:50 -04:00
parent 6dcfb351be
commit e9c23dc817
2 changed files with 11 additions and 1 deletions

View File

@ -11,7 +11,7 @@ module FactoryGirl
block = @block
-> {
value = block.arity == 1 ? block.call(self) : instance_exec(&block)
value = block.arity == 1 ? instance_exec(self, &block) : instance_exec(&block)
raise SequenceAbuseError if FactoryGirl::Sequence === value
value
}

View File

@ -38,4 +38,14 @@ describe "syntax methods within dynamic attributes" do
expect(FactoryGirl.build(:post).title).to eq "generate result"
expect(FactoryGirl.attributes_for(:post)[:title]).to be_nil
end
it 'allows syntax methods to be used when the block has an arity of 1' do
FactoryGirl.define do
factory :post_using_block_with_variable, parent: :post do
user {|_| build(:user) }
end
end
expect(FactoryGirl.build(:post_using_block_with_variable).user).to be_instance_of(User)
end
end