Skip to content

Commit

Permalink
version 0.6.0. now uses factory_girl-cache and fixed invalid syntax f…
Browse files Browse the repository at this point in the history
…or traits
  • Loading branch information
garysweaver committed Nov 6, 2012
1 parent d36cb8d commit a8d4f62
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 27 deletions.
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,14 @@ If working with a legacy schema, you may have models with foreign_key columns th

Use `--cache-associations` to store and use factories to avoid 'stack level too deep' errors.

This uses the [factory_girl-cache][factory_girl-cache] gem in the autogenerated factories, so you will need to include it also in your Gemfile:

gem 'factory_girl-cache'

and

bundle install

##### Specifying Models

Specify `--models` and a comma-delimited list of models to only output the models you specify. If you don't want to overwrite existing factory files, you should direct the output to another file and manually copy each in:
Expand Down Expand Up @@ -164,7 +172,7 @@ or referring to created objects through associations, though he said multiple ne

Copyright (c) 2012 Gary S. Weaver, released under the [MIT license][lic].

[singletons]: http://stackoverflow.com/questions/2015473/using-factory-girl-in-rails-with-associations-that-have-unique-constraints-gett/3569062#3569062
[factory_girl-cache]: https://github.com/garysweaver/factory_girl-cache
[test_factories]: https://github.com/thoughtbot/factory_girl/wiki/Testing-all-Factories-%28with-RSpec%29
[factory_girl]: https://github.com/thoughtbot/factory_girl/
[lic]: http://github.com/garysweaver/stepford/blob/master/LICENSE
36 changes: 11 additions & 25 deletions lib/stepford/factory_girl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,7 @@

module Stepford
class FactoryGirl
CACHE_VALUES_FILENAME = 'fg_cache.rb'

def self.generate_factories(options={})
# guard against circular references
if options[:cache_associations]
File.open(File.join(File.dirname(get_factories_rb_pathname(options)), CACHE_VALUES_FILENAME), "w") do |f|
#TODO: just copy this file from the gem to project vs. writing it like this
f.puts '# originally created by Stepford: https://github.com/garysweaver/stepford'
f.puts '# idea somewhat based on d2vid and snowangel\'s answer in http://stackoverflow.com/questions/2015473/using-factory-girl-in-rails-with-associations-that-have-unique-constraints-gett/3569062#3569062'
f.puts 'fg_cachehash = {}'
f.puts 'def fg_cache(class_sym, assc_sym = nil, number = nil)'
# if missing 3rd arg, assume 2nd arg is 3rd arg or use default
# if missing 2nd and 3rd arg, assume 2nd arg is 1st arg
f.puts ' number ||= assc_sym'
f.puts ' assc_sym ||= class_sym'
f.puts ' fg_cachehash[factory_sym, assc_sym, number] ||= (number ? FactoryGirl.create_list(class_sym, number) : FactoryGirl.create(class_sym))'
f.puts 'end'
end
end

factories = {}
expected = {}
included_models = options[:models] ? options[:models].split(',').collect{|s|s.strip}.compact : nil
Expand All @@ -44,13 +25,18 @@ def self.generate_factories(options={})
should_be_trait = !(options[:associations] || required) && options[:association_traits]
if options[:associations] || required || should_be_trait
if options[:cache_associations]
if reflection.macro == :has_many
"#{should_be_trait ? "trait #{"with_#{assc_sym}".to_sym.inspect} do; " : ''}after(:create) do |user, evaluator|; #{is_reserved?(assc_sym) ? 'self.' : ''}#{assc_sym} = fg_cache(#{clas_sym.inspect}#{clas_sym == assc_sym ? '' : ", #{assc_sym.inspect}"}, 2); end"
if reflection.macro == :has_many
#
"#{should_be_trait ? "trait #{"with_#{assc_sym}".to_sym.inspect} do; " : ''}after(:create) do |user, evaluator|; #{is_reserved?(assc_sym) ? 'self.' : ''}#{assc_sym} = FactoryGirlCache.create_list(#{clas_sym.inspect}#{clas_sym == assc_sym ? '' : ", #{assc_sym.inspect}"}, 2); end#{should_be_trait ? '; end' : ''}"
else
"#{should_be_trait ? "trait #{"with_#{assc_sym}".to_sym.inspect} do; " : ''}after(:create) do |user, evaluator|; #{is_reserved?(assc_sym) ? 'self.' : ''}#{assc_sym} = fg_cache(#{clas_sym.inspect}#{clas_sym == assc_sym ? '' : ", #{assc_sym.inspect}"}); end"
"#{should_be_trait ? "trait #{"with_#{assc_sym}".to_sym.inspect} do; " : ''}before(:build) do |user, evaluator|; #{is_reserved?(assc_sym) ? 'self.' : ''}#{assc_sym} = FactoryGirlCache.create(#{clas_sym.inspect}#{clas_sym == assc_sym ? '' : ", #{assc_sym.inspect}"}); end#{should_be_trait ? '; end' : ''}"
end
else
if reflection.macro == :has_many
if reflection.macro == :has_many
# In factory girl v4.1.0:
# create_list must be done in an after(:create) or you get Trait not registered or Factory not registered errors.
# this means that validators that verify presence or size > 0 in a association list will not work with this method, and you'll need to
# use build, not create: http://stackoverflow.com/questions/11209347/has-many-with-at-least-two-entries
"#{should_be_trait ? "trait #{"with_#{assc_sym}".to_sym.inspect} do; " : ''}#{should_be_trait || has_presence_validator ? '' : '#'}after(:create) do |user, evaluator|; FactoryGirl.create_list #{clas_sym.inspect}, 2; end#{should_be_trait ? '; end' : ''}#{should_be_trait ? '' : ' # commented to avoid circular reference'}"
elsif assc_sym != clas_sym
"#{should_be_trait ? "trait #{"with_#{assc_sym}".to_sym.inspect} do; " : ''}#{should_be_trait || reflection.macro == :belongs_to || has_presence_validator ? '' : '#'}association #{assc_sym.inspect}#{assc_sym != clas_sym ? ", factory: #{clas_sym.inspect}" : ''}#{should_be_trait ? '; end' : ''}#{should_be_trait || reflection.macro == :belongs_to ? '' : ' # commented to avoid circular reference'}"
Expand Down Expand Up @@ -159,9 +145,9 @@ def self.get_factories_rb_pathname(options)

def self.write_header(f, options)
f.puts 'require \'factory_girl_rails\''
f.puts "require_relative \'#{CACHE_VALUES_FILENAME.chomp('.rb')}\'" if options[:cache_associations]
f.puts 'require \'factory_girl-cache\'' if options[:cache_associations]
f.puts ''
f.puts '# originally created by Stepford: https://github.com/garysweaver/stepford'
f.puts '# original version autogenerated by Stepford: https://github.com/garysweaver/stepford'
f.puts ''
f.puts 'FactoryGirl.define do'
f.puts ' '
Expand Down
2 changes: 1 addition & 1 deletion lib/stepford/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module Stepford
VERSION = '0.5.0'
VERSION = '0.6.0'
end

0 comments on commit a8d4f62

Please sign in to comment.