Skip to content

Commit

Permalink
Allow factories with traits to be used in associations
Browse files Browse the repository at this point in the history
This allows defining associations with factories using traits by slicing
up the hash passed to association. Passing an array to `:factory` will
use the first item in the array as the factory, with any subsequent
symbols as traits.

Here's an example:

    factory :post do
      association :author, factory: [:user, :admin], name: 'John Doe'
    end

Closes thoughtbot#395
  • Loading branch information
joshuaclayton committed Jun 29, 2012
1 parent 5e90ff1 commit 4e2b7e0
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 3 deletions.
5 changes: 4 additions & 1 deletion lib/factory_girl/attribute/association.rb
Expand Up @@ -13,7 +13,10 @@ def initialize(name, factory, overrides)
def to_proc
factory = @factory
overrides = @overrides
-> { association(factory, overrides) }
traits_and_overrides = [factory, overrides].flatten
factory_name = traits_and_overrides.shift

-> { association(factory_name, *traits_and_overrides) }
end

def association?
Expand Down
7 changes: 5 additions & 2 deletions lib/factory_girl/evaluator.rb
Expand Up @@ -23,10 +23,13 @@ def initialize(build_class, build_strategy, overrides = {})

delegate :new, to: :@build_class

def association(factory_name, overrides = {})
def association(factory_name, *traits_and_overrides)
overrides = traits_and_overrides.extract_options!
strategy_override = overrides.fetch(:strategy) { :create }

runner = FactoryRunner.new(factory_name, strategy_override, [overrides.except(:strategy)])
traits_and_overrides += [overrides.except(:strategy)]

runner = FactoryRunner.new(factory_name, strategy_override, traits_and_overrides)
@build_strategy.association(runner)
end

Expand Down
29 changes: 29 additions & 0 deletions spec/acceptance/traits_spec.rb
Expand Up @@ -669,3 +669,32 @@ def initialize(name)
FactoryGirl.build(:user_with_trait_with_callback).value.should == 1
end
end

describe "traits used in associations" do
before do
define_model("User", admin: :boolean, name: :string)
define_model("Post", author_id: :integer) do
belongs_to :author, class_name: 'User'
end

FactoryGirl.define do
factory :user do
admin false

trait :admin do
admin true
end
end

factory :post do
association :author, factory: [:user, :admin], name: 'John Doe'
end
end
end

it "allows assigning traits for the factory of an association" do
author = FactoryGirl.create(:post).author
author.should be_admin
author.name.should == 'John Doe'
end
end

0 comments on commit 4e2b7e0

Please sign in to comment.