Module: Fixjour

Extended by:
Definitions
Defined in:
lib/fixjour/define.rb,
lib/fixjour/errors.rb,
lib/fixjour/verify.rb,
lib/fixjour/builder.rb,
lib/fixjour/counter.rb,
lib/fixjour/builders.rb,
lib/fixjour/generator.rb,
lib/fixjour/definitions.rb,
lib/fixjour/deprecation.rb,
lib/fixjour/merging_proxy.rb,
lib/fixjour/overrides_hash.rb,
lib/fixjour/redundant_check.rb

Defined Under Namespace

Modules: Definitions, Deprecation, RedundancyChecker Classes: Builder, BuilderSavedRecord, Counter, DangerousBuilder, DeprecatedMergeAttempt, Generator, InvalidBuilder, MergingProxy, NonBlockBuilderReference, OverridesHash, RedundantBuilder, UnsavableBuilder, WrongBuilderType

Class Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Definitions

define_create, define_new, define_valid_attributes

Class Attribute Details

.allow_redundancyObject

Returns the value of attribute allow_redundancy.



9
10
11
# File 'lib/fixjour/builders.rb', line 9

def allow_redundancy
  @allow_redundancy
end

Class Method Details

.allow_redundancy!Object



15
16
17
# File 'lib/fixjour/builders.rb', line 15

def allow_redundancy!
  @always_allow_redundancy = true
end

.allow_redundancy?Boolean

Returns:

  • (Boolean)


19
20
21
# File 'lib/fixjour/builders.rb', line 19

def allow_redundancy?
  @always_allow_redundancy || @allow_redundancy
end

.builder_defined?(builder) ⇒ Boolean

Checks to see whether or not a builder is defined. Duh.

Returns:

  • (Boolean)


62
63
64
65
66
67
68
# File 'lib/fixjour/builders.rb', line 62

def builder_defined?(builder)
  case builder
  when Class  then builders.values.map(&:klass).include?(builders)
  when String then builders.values.map(&:name).include?(builder)
  when Symbol then builders.values.map(&:name).include?(builder.to_s)
  end
end

.buildersObject

The list of classes that have builders defined.



24
25
26
# File 'lib/fixjour/builders.rb', line 24

def builders
  @builders ||= {}
end

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



2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# File 'lib/fixjour/define.rb', line 2

def self.define(object, options={}, &block)
  if builder = options[:from]
    name = builder.is_a?(Symbol) ? builder : Fixjour.send(:name_for, builder)
    Fixjour.define_builder(builder, :as => object) do |klass, overrides|
      # klass is NOT to be used in this case
      instance = send("new_#{name}")
      instance_exec(instance, &block)
      overrides.each { |key, val| instance[key] = val }
      instance
    end
  else
    Fixjour.define_builder(object, options) do |klass, overrides|
      instance = klass.new
      instance_exec(instance, &block)
      overrides.each { |key, val| instance[key] = val }
      instance
    end
  end
end

.define_builder(klass, options = {}, &block) ⇒ Object

This method should always return a valid instance of a model object.



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/fixjour/builders.rb', line 30

def define_builder(klass, options={}, &block)
  builder = Builder.new(klass, :as => options.delete(:as))
  add_builder(builder)

  if block_given?
    define_new(builder, &block)
  else
    define_new(builder) do |proxy, overrides|
      proxy.new(options.merge(overrides))
    end
  end

  define_create(builder)
  define_valid_attributes(builder)
end

.evaluate(&block) ⇒ Object

Adds builders to Fixjour.



47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/fixjour/builders.rb', line 47

def evaluate(&block)
  begin
    module_eval(&block)
  rescue NameError => e
    if e.name && evaluator.respond_to?(e.name)
      raise NonBlockBuilderReference.new(
        "You must use a builder block in order to reference other Fixjour creation methods."
      )
    else
      raise e
    end
  end
end

.included(klass) ⇒ Object



2
3
4
# File 'lib/fixjour/redundant_check.rb', line 2

def self.included(klass)
  klass.extend(RedundancyChecker) unless Fixjour.allow_redundancy?
end

.new_record(klass) ⇒ Object



45
46
47
# File 'lib/fixjour/verify.rb', line 45

def new_record(klass)
  evaluator.send("new_#{klass.name}")
end

.prohibit_redundancy!Object



11
12
13
# File 'lib/fixjour/builders.rb', line 11

def prohibit_redundancy!
  @always_allow_redundancy = false
end

.remove(klass) ⇒ Object



70
71
72
# File 'lib/fixjour/builders.rb', line 70

def remove(klass)
  builders.delete(Builder.new(klass).name)
end

.verify!Object

Checks each builder to ensure that they:

  • Return valid objects

  • The new_* methods return new records

  • The creation methods return objects of the proper type



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/fixjour/verify.rb', line 8

def verify!
  builders.each do |name, builder|
    klass = builder.klass
    result = new_record(builder)

    unless result.valid?
      error(klass, InvalidBuilder, "returns an invalid object: #{result.errors.inspect}")
    end

    unless result.new_record?
      error(klass, BuilderSavedRecord, "must return a new record")
    end

    unless result.is_a?(klass)
      error(klass, WrongBuilderType, "must return an instance of #{klass}")
    end

    klass.transaction do
      begin
        result.save!
      rescue => e
        error(klass, UnsavableBuilder, "raises #{e.inspect} when saved to the database")
      end

      unless new_record(builder).valid?
        msg = ""
        msg << "returns invalid an invalid object after another object has been saved.\n"
        msg << "This could be caused by a validates_uniqueness_of validation in your model.\n"
        msg << "Use something like the faker gem to alleviate this issue."
        error(klass, DangerousBuilder, msg)
      end

      raise ActiveRecord::Rollback
    end
  end
end

Instance Method Details

#counter(key = nil) ⇒ Object



2
3
4
# File 'lib/fixjour/builders.rb', line 2

def counter(key=nil)
  Counter.counter(key)
end