Class: Machine

Inherits:
Object
  • Object
show all
Defined in:
lib/machine/machine.rb

Class Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, options, proc) ⇒ Machine

:nodoc



207
208
209
# File 'lib/machine/machine.rb', line 207

def initialize(name, options, proc) #:nodoc
  @name, @options, @proc = name, options, proc
end

Class Attribute Details

.definition_file_pathsObject

Returns the value of attribute definition_file_paths.



16
17
18
# File 'lib/machine/machine.rb', line 16

def definition_file_paths
  @definition_file_paths
end

Class Method Details

.apply_to(name, object, attributes = {}) ⇒ Object

Apply the machine with the given name to the provided object. This can be used to load an existing object with the attributes defined in a machine.

Arguments:

name: (Symbol)
  The name of the machine to apply.
object: (Object)
  The object whose attributes should be set.
attributes: (Hash)
  A set of replacements attributes for those specified in the machine.

Example

car = Car.new
Machine.apply_to(:car, car, :model => 'Jetta')


158
159
160
161
162
163
164
165
# File 'lib/machine/machine.rb', line 158

def self.apply_to(name, object, attributes={})
  machines = machines_for(name)
  return if machines.empty?
  while machine = machines.shift
    machine.apply_to(object, attributes)
  end
  object    
end

.build(name, attributes = {}, &block) ⇒ Object

Creates an unsaved object using the machine with the given name.

Arguments:

name: (Symbol)
  The name of the machine to apply.
attributes: (Hash)
  A set of attributes to use as a replacement for the default ones provided by
  the machine.
block: (Proc, optional)
  If a block is passed to the function, it will attempt to call the block with
  the newly created object as an argument so that manual initialization can be
  done. This can be used in combination with or instead of passing an attributes hash.

Example

Machine.build(:car, :model => 'Civic', :make => 'Honda')


110
111
112
113
114
115
116
117
118
119
# File 'lib/machine/machine.rb', line 110

def self.build(name, attributes={}, &block)
  machines = machines_for(name)
  raise MachineNotFoundError if machines.empty?
  object = machines.shift.build(attributes)
  while machine = machines.shift
    machine.apply_to(object, attributes)
  end
  block.call(object) if block_given?
  object
end

.build!(name, attributes = {}, &block) ⇒ Object

Creates an saved object using the machine with the given name.

Arguments:

name: (Symbol)
  The name of the machine to apply.
attributes: (Hash)
  A set of attributes to use as a replacement for the default ones provided by
  the machine.
block: (Proc, optional)
  If a block is passed to the function, it will attempt to call the block with
  the newly created object as an argument so that manual initialization can be
  done. This can be used in combination with or instead of passing an attributes hash.

Example

Machine.build!(:car, :model => 'Civic', :make => 'Honda')


137
138
139
140
141
# File 'lib/machine/machine.rb', line 137

def self.build!(name, attributes={}, &block)
  result = build(name, attributes, &block)
  result.save! if result.respond_to?(:save!)
  result
end

.define(name, options = {}, &block) ⇒ Object

Defines a new machine that sets up the default attributes for new objects.

Arguments:

name: (Symbol)
  A unique name used to identify this machine.
options: (Hash)
  class: (Class) the class that will be used when generating instances for this
         machine. If not specified, the class will be guessed from the 
         machine name.
  extends: (Symbol) the name of a machine that will be extended by this one.
           If provided, the attributes of the extended machine will be applied
           to the object before the one being defined.

Yields:

The object being created and an association helper

Example:

Machine.define :car do |car, machine|
  car.make = 'GMC'
  car.model = 'S-15'
end


53
54
55
# File 'lib/machine/machine.rb', line 53

def self.define(name, options={}, &block)
  self.machines[name] = Machine.new(name, options, block)
end

.define_group(name, options = {}) {|group| ... } ⇒ Object

Defines a group of machines with a base set of attributes and then a set of machines as children. This is useful as a namespacing technique or for any case where you wish to define a set of objects that share a set of base attributes.

Arguments:

name: (Symbol)
  A unique name to identify the group. This name will itself become a machine
  that will build from the base attributes.
options: (Hash)
  class: (Class) the class that will be used when generating instances for this
         machine. If not specified, the class will be guessed from the 
         machine name.

Example

Machine.define_group :user do |group|
  group.base do |user, machine|
    user.password = 'password'
    user.password_confirmation = 'password'
    user. = Machine.next(:login)
    user.email = Machine.next(:email)
  end

  group.define :super_user do |user, machine|
    user.permissions = [machine.permission(:user => user)]
  end
end

Machine.build(:user)
Machine.build(:super_user)

Yields:

  • (group)


89
90
91
92
# File 'lib/machine/machine.rb', line 89

def self.define_group(name, options={}, &block)
  group = MachineGroup.new(name, options)
  yield group
end

.find_definitionsObject

:nodoc:



21
22
23
24
25
26
27
28
29
# File 'lib/machine/machine.rb', line 21

def self.find_definitions #:nodoc:
  definition_file_paths.each do |file_path|
    begin
      require(file_path)
      break
    rescue LoadError
    end
  end
end

.next(sequence) ⇒ Object

Get the next value produced by the sequence with the given name. This can be used in machine definitions to fill in attributes that must be unique.

Arguments:

sequence: (Symbol)
  The name of the sequence to use.

Example

Machine.define :address do |address, machine|
  address.street = machine.next(:street)
end


202
203
204
205
# File 'lib/machine/machine.rb', line 202

def self.next(sequence)
  raise MachineNotFoundError unless sequences.has_key?(sequence)
  sequences[sequence].next
end

.sequence(name, &block) ⇒ Object

Defines a new named sequence. Sequences can be used to set attributes that must be unique. Once a sequence is created it can be applied by calling Machine.next, passing the sequence name.

Arguments:

name: (Symbol)
  A unique name used to identify this sequence.
block: (Proc)
  The code to generate each value in the sequence. This block will be
  called with a unique number each time a value in the sequence is to be
  generated. The block should return the generated value for the
  sequence.

Example

Machine.sequence :street do |n|
  "#{n} Main St."
end


185
186
187
# File 'lib/machine/machine.rb', line 185

def self.sequence(name, &block)
  self.sequences[name] = Sequence.new(block)
end

Instance Method Details

#apply_to(object, attributes = {}) ⇒ Object

:nodoc



221
222
223
224
# File 'lib/machine/machine.rb', line 221

def apply_to(object, attributes={}) #:nodoc
  @proc.call(object, AssociationHelper.new)
  attributes.each { |key, value| object.send("#{key}=", value) }
end

#build(attributes = {}) ⇒ Object

:nodoc



215
216
217
218
219
# File 'lib/machine/machine.rb', line 215

def build(attributes={}) #:nodoc
  object = build_class.new
  apply_to(object, attributes)
  object
end

#extendsObject

:nodoc



211
212
213
# File 'lib/machine/machine.rb', line 211

def extends #:nodoc
  @options[:extends] ? machines[@options[:extends]] : nil
end