model-builder 2.0.0 → 2.1.0
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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/README.rdoc +15 -7
- data/lib/model_builder/class_builder.rb +23 -10
- data/lib/model_builder/version.rb +1 -1
- data/lib/model_builder.rb +9 -13
- data/spec/lib/model_builder/class_builder_spec.rb +1 -6
- data/spec/lib/model_builder_spec.rb +7 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 43d4553c2249d1ed6c3191c3177246b5cb3afb1e
|
4
|
+
data.tar.gz: e55a8406071a5161677595830d4aa6030721bbc1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 61b3c213aead2ae4b7ed17ac861e04ff06cf55a403beba99eefb1233e8a42331c1f9b32632f4f79796137021f79d5a6f5fff6fadaa8d2d0bb3460d05b9ad9c75
|
7
|
+
data.tar.gz: ac98d9910802a38209c7078a90f821a338cb37144fb6bddf855e4d0a15053d4b60bb6cab5adbece32f0df835c7e74c256cc66b0a5b4e3c6af91d624d84019c38
|
data/.gitignore
CHANGED
data/README.rdoc
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
Build active record models on the fly.
|
4
4
|
|
5
|
-
Handy when
|
5
|
+
Handy when following TDD to develop a reusable component, that isn't strictly related to a project business intelligence (therefore should not reference it).
|
6
6
|
|
7
7
|
== Scenario
|
8
8
|
|
9
|
-
|
9
|
+
Take a look at this case of code duplication:
|
10
10
|
|
11
11
|
class User < ActiveRecord::Base
|
12
12
|
def map_all_names
|
@@ -20,7 +20,7 @@ Consider this case of code duplication:
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
-
|
23
|
+
That can be easily improved through an abstraction:
|
24
24
|
|
25
25
|
class User < ActiveRecord::Base
|
26
26
|
include NameUtils
|
@@ -38,12 +38,12 @@ We can easily improve this through an abstraction:
|
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
|
-
Nice. Now we
|
41
|
+
Nice. Now we've a reusable abstraction, that could even fit into a gem to be applied at another projects.
|
42
42
|
|
43
|
-
But thinking about
|
43
|
+
But thinking about a gem context, we will not be able to use User or Topic models at our tests.
|
44
44
|
They belong to our business intelligence. So, how to test it?
|
45
45
|
|
46
|
-
Here
|
46
|
+
Here is the need of don't rely our business intelligence during abstraction tests.
|
47
47
|
|
48
48
|
== Solution
|
49
49
|
|
@@ -57,4 +57,12 @@ Now your 'MappableName' model is able to receive NameUtils tests:
|
|
57
57
|
|
58
58
|
MappableName.map_all_names
|
59
59
|
|
60
|
-
See
|
60
|
+
See full test examples here[https://github.com/r4z3c/model-builder/blob/master/spec/examples/name_utils_spec.rb] and here[https://github.com/r4z3c/model-builder/blob/master/spec/lib/model_builder_spec.rb].
|
61
|
+
|
62
|
+
== Changelog
|
63
|
+
|
64
|
+
=== 2.1.0
|
65
|
+
|
66
|
+
- Improving support to namespaced classes/models. Now the builder accepts:
|
67
|
+
|
68
|
+
ModelBuilder.build 'Namespaced::Models' ...
|
@@ -3,21 +3,38 @@ module ModelBuilder
|
|
3
3
|
|
4
4
|
@@dynamic_classes ||= {}
|
5
5
|
|
6
|
-
def self.build(
|
7
|
-
|
6
|
+
def self.build(class_full_name, opts={})
|
7
|
+
namespace = namespace_from_class_full_name class_full_name
|
8
|
+
class_name = class_name_from_class_full_name class_full_name
|
9
|
+
return namespace.const_get class_name if namespace.const_defined? class_name
|
8
10
|
|
9
11
|
klass = get_class_from_options opts
|
10
|
-
|
12
|
+
namespace.const_set class_name, klass
|
11
13
|
|
12
|
-
|
13
|
-
|
14
|
-
add_class mod, klass
|
14
|
+
add_class namespace, klass
|
15
15
|
include_modules klass, opts[:includes]
|
16
16
|
create_accessors klass, opts[:accessors]
|
17
17
|
|
18
18
|
klass
|
19
19
|
end
|
20
20
|
|
21
|
+
def self.namespace_from_class_full_name(class_full_name)
|
22
|
+
namespace_name = class_namespace_name(class_full_name)
|
23
|
+
namespace_name.blank? ? Object : const_get(namespace_name)
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.class_namespace_name(class_full_name)
|
27
|
+
class_full_name_parts(class_full_name)[0...-1].join '::'
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.class_full_name_parts(class_full_name)
|
31
|
+
class_full_name.split('::')
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.class_name_from_class_full_name(class_full_name)
|
35
|
+
class_full_name_parts(class_full_name).last
|
36
|
+
end
|
37
|
+
|
21
38
|
def self.get_class_from_options(opts)
|
22
39
|
superclass = get_superclass_from_options opts
|
23
40
|
superclass.nil? ? Class.new : Class.new(superclass)
|
@@ -28,10 +45,6 @@ module ModelBuilder
|
|
28
45
|
superclass.is_a?(String) ? superclass.constantize : superclass
|
29
46
|
end
|
30
47
|
|
31
|
-
def self.get_module_from_options(opts)
|
32
|
-
opts[:module] || Object
|
33
|
-
end
|
34
|
-
|
35
48
|
def self.add_class(mod, klass)
|
36
49
|
@@dynamic_classes[mod] = klass
|
37
50
|
end
|
data/lib/model_builder.rb
CHANGED
@@ -4,14 +4,14 @@ module ModelBuilder
|
|
4
4
|
|
5
5
|
@@dynamic_models ||= []
|
6
6
|
|
7
|
-
def self.build(
|
7
|
+
def self.build(class_full_name, opts={})
|
8
8
|
opts.reverse_merge! get_default_options
|
9
9
|
|
10
|
-
already_exists = Object.const_defined?
|
11
|
-
klass = ClassBuilder.build
|
10
|
+
already_exists = Object.const_defined? class_full_name
|
11
|
+
klass = ClassBuilder.build class_full_name, opts
|
12
12
|
|
13
13
|
unless already_exists
|
14
|
-
create_table
|
14
|
+
create_table class_full_name, opts
|
15
15
|
define_validations klass, opts[:validates]
|
16
16
|
end
|
17
17
|
|
@@ -25,16 +25,12 @@ module ModelBuilder
|
|
25
25
|
}
|
26
26
|
end
|
27
27
|
|
28
|
-
def self.create_table(
|
29
|
-
ActiveRecord::Migration.create_table(
|
28
|
+
def self.create_table(class_full_name, opts)
|
29
|
+
ActiveRecord::Migration.create_table(class_full_name.tableize) do |migration|
|
30
30
|
create_attributes(migration, opts[:attributes])
|
31
31
|
end
|
32
32
|
|
33
|
-
@@dynamic_models <<
|
34
|
-
end
|
35
|
-
|
36
|
-
def self.table_name_for(klass)
|
37
|
-
klass.to_s.tableize
|
33
|
+
@@dynamic_models << class_full_name
|
38
34
|
end
|
39
35
|
|
40
36
|
def self.create_attributes(migration, attributes={})
|
@@ -70,8 +66,8 @@ module ModelBuilder
|
|
70
66
|
@@dynamic_models
|
71
67
|
end
|
72
68
|
|
73
|
-
def self.drop_table(
|
74
|
-
ActiveRecord::Migration.drop_table(
|
69
|
+
def self.drop_table(class_full_name)
|
70
|
+
ActiveRecord::Migration.drop_table(class_full_name.tableize)
|
75
71
|
end
|
76
72
|
|
77
73
|
end
|
@@ -24,12 +24,7 @@ describe ModelBuilder::ClassBuilder do
|
|
24
24
|
it { expect(builder.dynamic_classes.values).to include constant }
|
25
25
|
|
26
26
|
context 'module validations' do
|
27
|
-
let(:
|
28
|
-
module: ModelBuilder,
|
29
|
-
superclass: Array,
|
30
|
-
includes: [Spec::Support::DummyModule],
|
31
|
-
accessors: %w(a1 a2)
|
32
|
-
}}
|
27
|
+
let(:name) { 'ModelBuilder::ClassBuilderTest' }
|
33
28
|
|
34
29
|
it { is_expected.to eq ModelBuilder.const_get(name) }
|
35
30
|
end
|
@@ -36,7 +36,13 @@ describe ModelBuilder do
|
|
36
36
|
subject { @build_result }
|
37
37
|
|
38
38
|
it { is_expected.to eq constant }
|
39
|
-
it { expect(builder.dynamic_models).to include
|
39
|
+
it { expect(builder.dynamic_models).to include name }
|
40
|
+
|
41
|
+
context 'module validations' do
|
42
|
+
let(:name) { 'ModelBuilder::TestModel' }
|
43
|
+
|
44
|
+
it { is_expected.to eq ModelBuilder.const_get(name) }
|
45
|
+
end
|
40
46
|
|
41
47
|
context 'options validations' do
|
42
48
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: model-builder
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- r4z3c
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-05-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|