fixjour 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/core_ext/hash.rb +9 -0
- data/lib/fixjour/builders.rb +68 -0
- data/lib/fixjour/errors.rb +14 -0
- data/lib/fixjour/verify.rb +36 -0
- data/lib/fixjour.rb +14 -0
- metadata +68 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
module Fixjour
|
|
2
|
+
class << self
|
|
3
|
+
# The list of classes that have builders defined.
|
|
4
|
+
def builders
|
|
5
|
+
@builders ||= Set.new
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
# Registers a class' builder. This allows us to make sure
|
|
9
|
+
# redundant builders aren't defined, which can lead to confusion
|
|
10
|
+
# when trying to figure out where objects are being created.
|
|
11
|
+
def add_builder(klass)
|
|
12
|
+
unless builders.add?(klass)
|
|
13
|
+
raise RedundantBuilder.new("You already defined a builder for #{klass.inspect}")
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# This method should always return a valid instance of
|
|
18
|
+
# a model object.
|
|
19
|
+
def define_builder(klass, &block)
|
|
20
|
+
add_builder(klass)
|
|
21
|
+
|
|
22
|
+
name = name_for(klass)
|
|
23
|
+
|
|
24
|
+
define_new(name, block)
|
|
25
|
+
define_create(name)
|
|
26
|
+
define_valid_attributes(name)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
def name_for(klass)
|
|
32
|
+
klass.model_name.singular
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Defines the new_* method
|
|
36
|
+
def define_new(name, block)
|
|
37
|
+
define_method("new_#{name}") do |*args|
|
|
38
|
+
overrides = args.first || { }
|
|
39
|
+
block.bind(self).call(overrides)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Defines the create_* method
|
|
44
|
+
def define_create(name)
|
|
45
|
+
define_method("create_#{name}") do |*args|
|
|
46
|
+
model = send("new_#{name}", *args)
|
|
47
|
+
model.save!
|
|
48
|
+
model
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Defines the valid_*_attributes method
|
|
53
|
+
def define_valid_attributes(name)
|
|
54
|
+
define_method("valid_#{name}_attributes") do |*args|
|
|
55
|
+
if instance_variable_get("@__valid_#{name}_attrs").nil?
|
|
56
|
+
valid_attributes = send("new_#{name}").attributes
|
|
57
|
+
valid_attributes.delete_if { |key, value| value.nil? }
|
|
58
|
+
instance_variable_set("@__valid_#{name}_attrs", valid_attributes)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
overrides = args.extract_options!
|
|
62
|
+
attrs = instance_variable_get("@__valid_#{name}_attrs").merge(overrides)
|
|
63
|
+
attrs.make_indifferent!
|
|
64
|
+
attrs
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module Fixjour
|
|
2
|
+
# Raised when a builder returns an invalid object
|
|
3
|
+
class InvalidBuilder < StandardError; end
|
|
4
|
+
|
|
5
|
+
# Raised when a builder returns an object of the wrong type
|
|
6
|
+
class WrongBuilderType < StandardError; end
|
|
7
|
+
|
|
8
|
+
# Raised when a builder is defined for a class that already
|
|
9
|
+
# has one.
|
|
10
|
+
class RedundantBuilder < StandardError; end
|
|
11
|
+
|
|
12
|
+
# Raised when a builder block saves the object.
|
|
13
|
+
class BuilderSavedRecord < StandardError; end
|
|
14
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
module Fixjour
|
|
2
|
+
class << self
|
|
3
|
+
# Checks each builder to ensure that they:
|
|
4
|
+
#
|
|
5
|
+
# * Return valid objects
|
|
6
|
+
# * The new_* methods return new records
|
|
7
|
+
# * The creation methods return objects of the proper type
|
|
8
|
+
def verify!
|
|
9
|
+
builders.each do |klass|
|
|
10
|
+
result = validity_checker.send("new_#{name_for(klass)}")
|
|
11
|
+
|
|
12
|
+
unless result.valid?
|
|
13
|
+
raise InvalidBuilder.new("The builder for #{klass} returns an invalid object")
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
unless result.new_record?
|
|
17
|
+
raise BuilderSavedRecord.new("The builder for #{klass} must not save the object")
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
unless result.is_a?(klass)
|
|
21
|
+
raise WrongBuilderType.new("The builder for #{klass} must return instance of #{klass}")
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
def validity_checker
|
|
29
|
+
@evaluator ||= begin
|
|
30
|
+
klass = Class.new
|
|
31
|
+
klass.send :include, self
|
|
32
|
+
klass.new
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
data/lib/fixjour.rb
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
$LOAD_PATH << File.dirname(__FILE__)
|
|
2
|
+
|
|
3
|
+
require 'rubygems'
|
|
4
|
+
require 'activerecord'
|
|
5
|
+
require 'core_ext/hash'
|
|
6
|
+
require 'fixjour/verify'
|
|
7
|
+
require 'fixjour/errors'
|
|
8
|
+
require 'fixjour/builders'
|
|
9
|
+
|
|
10
|
+
# This method is just for prettiness
|
|
11
|
+
def Fixjour(&block)
|
|
12
|
+
return Fixjour unless block_given?
|
|
13
|
+
Fixjour.module_eval(&block)
|
|
14
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: fixjour
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Pat Nakajima
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
|
|
12
|
+
date: 2008-12-29 00:00:00 -05:00
|
|
13
|
+
default_executable:
|
|
14
|
+
dependencies:
|
|
15
|
+
- !ruby/object:Gem::Dependency
|
|
16
|
+
name: activerecord
|
|
17
|
+
type: :runtime
|
|
18
|
+
version_requirement:
|
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
20
|
+
requirements:
|
|
21
|
+
- - ">="
|
|
22
|
+
- !ruby/object:Gem::Version
|
|
23
|
+
version: "0"
|
|
24
|
+
version:
|
|
25
|
+
description:
|
|
26
|
+
email: patnakajima@gmail.com
|
|
27
|
+
executables: []
|
|
28
|
+
|
|
29
|
+
extensions: []
|
|
30
|
+
|
|
31
|
+
extra_rdoc_files: []
|
|
32
|
+
|
|
33
|
+
files:
|
|
34
|
+
- lib/core_ext
|
|
35
|
+
- lib/core_ext/hash.rb
|
|
36
|
+
- lib/fixjour
|
|
37
|
+
- lib/fixjour/builders.rb
|
|
38
|
+
- lib/fixjour/errors.rb
|
|
39
|
+
- lib/fixjour/verify.rb
|
|
40
|
+
- lib/fixjour.rb
|
|
41
|
+
has_rdoc: true
|
|
42
|
+
homepage: http://github.com/nakajima/fixjour
|
|
43
|
+
post_install_message:
|
|
44
|
+
rdoc_options: []
|
|
45
|
+
|
|
46
|
+
require_paths:
|
|
47
|
+
- lib
|
|
48
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
49
|
+
requirements:
|
|
50
|
+
- - ">="
|
|
51
|
+
- !ruby/object:Gem::Version
|
|
52
|
+
version: "0"
|
|
53
|
+
version:
|
|
54
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
55
|
+
requirements:
|
|
56
|
+
- - ">="
|
|
57
|
+
- !ruby/object:Gem::Version
|
|
58
|
+
version: "0"
|
|
59
|
+
version:
|
|
60
|
+
requirements: []
|
|
61
|
+
|
|
62
|
+
rubyforge_project:
|
|
63
|
+
rubygems_version: 1.3.1
|
|
64
|
+
signing_key:
|
|
65
|
+
specification_version: 2
|
|
66
|
+
summary: Object creation methods everyone already has
|
|
67
|
+
test_files: []
|
|
68
|
+
|