class Factory class AttributeProxy attr_accessor :factory, :attribute_name, :strategy, :current_values #:nodoc: def initialize (factory, attr, strategy, values) #:nodoc: @factory = factory @attribute_name = attr @strategy = strategy @current_values = values end # Generates an association using the current build strategy. # # Arguments: # name: (Symbol) # The name of the factory that should be used to generate this # association. # attributes: (Hash) # A hash of attributes that should be overridden for this association. # # Returns: # The generated association for the current build strategy. Note that # assocaitions are not generated for the attributes_for strategy. Returns # nil in this case. # # Example: # # Factory.define :user do |f| # # ... # end # # Factory.define :post do |f| # # ... # f.author {|a| a.association :user, :name => 'Joe' } # end # # # Builds (but doesn't save) a Post and a User # Factory.build(:post) # # # Builds and saves a User, builds a Post, assigns the User to the # # author association, and saves the User. # Factory.create(:post) # def association (name, attributes = {}) if strategy == :attributes_for nil else Factory.send(strategy, name, attributes) end end # Returns the value for specified attribute. A value will only be available # if it was overridden when calling the factory, or if a value is added # earlier in the definition of the factory. # # Arguments: # attribute: (Symbol) # The attribute whose value should be returned. # # Returns: # The value of the requested attribute. (Object) def value_for (attribute) unless current_values.key?(attribute) raise ArgumentError, "No such attribute: #{attribute.inspect}" end current_values[attribute] end # Undefined methods are delegated to value_for, which means that: # # Factory.define :user do |f| # f.first_name 'Ben' # f.last_name {|a| a.value_for(:first_name) } # end # # and: # # Factory.define :user do |f| # f.first_name 'Ben' # f.last_name {|a| a.first_name } # end # # are equivilent. def method_missing (name, *args, &block) current_values[name] end end end