datamappify 0.2.2 → 0.9.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 +7 -0
- data/.gitignore +2 -0
- data/.travis.yml +4 -0
- data/CHANGELOG.md +5 -0
- data/Gemfile +4 -0
- data/README.md +69 -78
- data/Rakefile +20 -13
- data/datamappify.gemspec +29 -57
- data/lib/datamappify.rb +7 -16
- data/lib/datamappify/data.rb +6 -0
- data/lib/datamappify/data/association_methods.rb +29 -0
- data/lib/datamappify/data/base.rb +11 -0
- data/lib/datamappify/entity.rb +44 -0
- data/lib/datamappify/entity/associated_collection.rb +28 -0
- data/lib/datamappify/entity/associated_entity.rb +28 -0
- data/lib/datamappify/entity/association_methods.rb +20 -0
- data/lib/datamappify/repository.rb +65 -0
- data/lib/datamappify/repository/persistence.rb +38 -0
- data/lib/datamappify/version.rb +3 -0
- data/spec/entity_spec.rb +83 -0
- data/spec/repository/finders_and_persistence_spec.rb +71 -0
- data/spec/repository_spec.rb +60 -0
- data/spec/spec_helper.rb +24 -0
- data/spec/support/active_record_tables.rb +34 -0
- data/spec/support/comment.rb +9 -0
- data/spec/support/role.rb +9 -0
- data/spec/support/user.rb +21 -0
- metadata +244 -79
- data/MIT-LICENSE +0 -20
- data/VERSION +0 -1
- data/lib/datamappify/associations.rb +0 -21
- data/lib/datamappify/collection.rb +0 -46
- data/lib/datamappify/fake/column.rb +0 -17
- data/lib/datamappify/fake/connection.rb +0 -77
- data/lib/datamappify/fake/index.rb +0 -34
- data/lib/datamappify/railtie.rb +0 -10
- data/lib/datamappify/resource.rb +0 -35
- data/lib/datamappify/schema_dumper.rb +0 -21
- data/lib/tasks/datamappify.rake +0 -15
- data/vendor/auto_migrations/MIT-LICENSE +0 -20
- data/vendor/auto_migrations/README +0 -46
- data/vendor/auto_migrations/Rakefile +0 -24
- data/vendor/auto_migrations/init.rb +0 -2
- data/vendor/auto_migrations/lib/auto_migrations.rb +0 -178
- data/vendor/auto_migrations/lib/tasks/auto_migrations_tasks.rake +0 -20
- data/vendor/auto_migrations/test/auto_migrations_test.rb +0 -8
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 5cd51d61440490e0e15894ce7243cb4c324945b5
|
4
|
+
data.tar.gz: cbbf430016eaf1c88b181806e3901a009ce9028f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 55ecbac18bf660597c7494a12b9adf88a1597202388ae131305653c2e5902d4d455d284b37bc1ebd0e4bec82b408ea4e778198df07e4c819c264af34658a3200
|
7
|
+
data.tar.gz: 5bbc77d5ef8a8522e66461bead4a94490932138464f27d912593d8bf5ef26414bb26712c63b2f2ce234ed48b99f1fe37d5ee58959057c94f471799983282c2b8
|
data/.gitignore
CHANGED
data/.travis.yml
ADDED
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/README.md
CHANGED
@@ -1,118 +1,109 @@
|
|
1
|
-
# Datamappify
|
1
|
+
# Datamappify [](http://badge.fury.io/rb/datamappify) [](http://travis-ci.org/fredwu/datamappify) [](https://codeclimate.com/github/fredwu/datamappify)
|
2
2
|
|
3
|
-
|
3
|
+
Separate domain logic from data persistence, based on the [Repository Pattern](http://martinfowler.com/eaaCatalog/repository.html).
|
4
4
|
|
5
|
-
|
5
|
+
__This library is current in Proof-of-Concept stage, do NOT use it for anything other than experimentation.__
|
6
6
|
|
7
|
-
|
7
|
+
## Overview
|
8
8
|
|
9
|
-
|
9
|
+
Datamappify is a thin layer on top of ActiveRecord and [Virtus](https://github.com/solnic/virtus). The design goal is to utilise ActiveRecord but separate domain logic (behaviour) and data persistence.
|
10
10
|
|
11
|
-
|
11
|
+
Datamappify consists of three components:
|
12
12
|
|
13
|
-
|
13
|
+
- Entity
|
14
|
+
- Data
|
15
|
+
- Repository
|
14
16
|
|
15
|
-
|
16
|
-
* Possibly refactor `add_index` to be part of the `property` definition (as seen in the [DataMapper](http://datamapper.org/) library)
|
17
|
+
__Entity__ is your model, it is responsible for mainly storing behaviour. Some structure (i.e. model relationships) is also stored here for convenience.
|
17
18
|
|
18
|
-
|
19
|
+
__Data__ as the name suggests, holds your model data. It is an ActiveRecord object.
|
19
20
|
|
20
|
-
|
21
|
+
__Repository__ is responsible for data retrieval and persistence, e.g. `find`, `save` and `destroy`, etc.
|
21
22
|
|
22
|
-
|
23
|
-
|
24
|
-
### Why Not Use DataMapper, Sequel, etc?
|
25
|
-
|
26
|
-
As stated in the introduction, ActiveRecord is the most popular ORM in the rails community, it is actively developed and battle-tested. If your only grief with ActiveRecord is the DB migrations, why not just eliminate it be happy? ;)
|
27
|
-
|
28
|
-
## How?
|
29
|
-
|
30
|
-
How does this plugin work?
|
23
|
+
## Installation
|
31
24
|
|
32
|
-
|
25
|
+
Add this line to your application's Gemfile:
|
33
26
|
|
34
|
-
|
35
|
-
2. `schema.rb` is automatically updated according to the model properties.
|
36
|
-
3. Automatically 'migrates' the database according to the updated schema file.
|
27
|
+
gem 'datamappify'
|
37
28
|
|
38
|
-
|
29
|
+
And then execute:
|
39
30
|
|
40
|
-
|
31
|
+
$ bundle
|
41
32
|
|
42
|
-
|
33
|
+
Or install it yourself as:
|
43
34
|
|
44
|
-
gem
|
35
|
+
$ gem install datamappify
|
45
36
|
|
46
37
|
## Usage
|
47
38
|
|
48
|
-
|
39
|
+
Model:
|
49
40
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
property :email, :string
|
54
|
-
property :password, :string, :limit => 40
|
55
|
-
property :first_name, :string, :limit => 50
|
56
|
-
property :last_name, :string, :limit => 50
|
57
|
-
property :payment_email, :string
|
58
|
-
property :timestamps
|
59
|
-
add_index :email
|
60
|
-
add_index :payment_email
|
61
|
-
add_index :role_id
|
62
|
-
|
63
|
-
belongs_to :role
|
64
|
-
end
|
41
|
+
```ruby
|
42
|
+
class User
|
43
|
+
include Datamappify::Entity
|
65
44
|
|
66
|
-
|
45
|
+
attribute :first_name, String
|
46
|
+
attribute :last_name, String
|
47
|
+
attribute :age, Integer
|
67
48
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
t.string :last_name, :limit => nil
|
73
|
-
t.string :payment_email, :limit => nil
|
74
|
-
t.integer :role_id, :limit => nil
|
75
|
-
t.datetime :created_at
|
76
|
-
t.datetime :updated_at
|
77
|
-
end
|
49
|
+
# ActiveModel::Validations rules are wrapped in the `validations` block
|
50
|
+
validations do
|
51
|
+
validates :first_name, :presence => true
|
52
|
+
end
|
78
53
|
|
79
|
-
|
80
|
-
|
81
|
-
|
54
|
+
# ActiveRelation collections are wrapped in the `relationships` block
|
55
|
+
relationships do
|
56
|
+
has_one :role
|
57
|
+
has_many :comments
|
58
|
+
end
|
82
59
|
|
83
|
-
|
60
|
+
def full_name
|
61
|
+
"#{first_name} #{last_name}"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
```
|
84
65
|
|
85
|
-
|
66
|
+
Corresponding repository:
|
86
67
|
|
87
|
-
|
88
|
-
|
89
|
-
|
68
|
+
```ruby
|
69
|
+
user_repository = Datamappify::Repository.new(User)
|
70
|
+
```
|
90
71
|
|
91
|
-
|
72
|
+
Retrieving records:
|
92
73
|
|
93
|
-
|
74
|
+
```ruby
|
75
|
+
user = user_repository.find(1)
|
76
|
+
```
|
94
77
|
|
95
|
-
|
96
|
-
3. Index options such as `name`, `unique` and `length`.
|
78
|
+
Saving/updating a record:
|
97
79
|
|
98
|
-
|
80
|
+
```ruby
|
81
|
+
user_repository.save(user)
|
82
|
+
```
|
99
83
|
|
100
|
-
|
84
|
+
Destroying a record:
|
101
85
|
|
102
|
-
|
103
|
-
|
86
|
+
```ruby
|
87
|
+
user_repository.destroy(user)
|
88
|
+
```
|
104
89
|
|
105
|
-
|
90
|
+
## Todo
|
106
91
|
|
107
|
-
|
92
|
+
- Entity should dictate Data, so schema and migrations should be automatically generated
|
93
|
+
- Support for `set_primary_key` (currently the PK is hard coded to `id`)
|
94
|
+
- Support for HABTM association type
|
95
|
+
- Support for entity attribute and data column mapping
|
96
|
+
- Repository should handle asscociated data
|
108
97
|
|
109
|
-
|
98
|
+
## Similar Projects
|
110
99
|
|
111
|
-
|
100
|
+
- [Curator](https://github.com/braintree/curator)
|
101
|
+
- [Edr](https://github.com/nulogy/edr)
|
112
102
|
|
113
103
|
## Author
|
114
104
|
|
115
|
-
|
105
|
+
[Fred Wu](http://fredwu.me/)
|
106
|
+
|
107
|
+
## License
|
116
108
|
|
117
|
-
|
118
|
-
* Wuit - <http://wuit.com>
|
109
|
+
Licensed under [MIT](http://fredwu.mit-license.org/)
|
data/Rakefile
CHANGED
@@ -1,18 +1,25 @@
|
|
1
|
-
require
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require 'rake/testtask'
|
3
|
+
|
4
|
+
Rake::TestTask.new do |t|
|
5
|
+
t.libs.push 'lib'
|
6
|
+
t.test_files = FileList['spec/**/*_spec.rb']
|
7
|
+
t.verbose = true
|
8
|
+
end
|
2
9
|
|
3
10
|
begin
|
4
|
-
require '
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
s.add_dependency("activerecord")
|
11
|
+
require 'cane/rake_task'
|
12
|
+
|
13
|
+
desc "Run cane to check quality metrics"
|
14
|
+
Cane::RakeTask.new(:quality) do |cane|
|
15
|
+
cane.abc_max = 8
|
16
|
+
cane.no_doc = true
|
17
|
+
cane.style_glob = './lib/**/*.rb'
|
18
|
+
cane.style_measure = 120
|
19
|
+
cane.abc_exclude = []
|
14
20
|
end
|
15
|
-
Jeweler::GemcutterTasks.new
|
16
21
|
rescue LoadError
|
17
|
-
|
22
|
+
warn "cane not available, quality task not provided."
|
18
23
|
end
|
24
|
+
|
25
|
+
task :default => [:test, :quality]
|
data/datamappify.gemspec
CHANGED
@@ -1,62 +1,34 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'datamappify/version'
|
5
5
|
|
6
|
-
Gem::Specification.new do |
|
7
|
-
|
8
|
-
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "datamappify"
|
8
|
+
spec.version = Datamappify::VERSION
|
9
|
+
spec.authors = ["Fred Wu"]
|
10
|
+
spec.email = ["ifredwu@gmail.com"]
|
11
|
+
spec.description = %q{Separate domain logic from data persistence.}
|
12
|
+
spec.summary = spec.description
|
13
|
+
spec.homepage = "https://github.com/fredwu/datamappify"
|
14
|
+
spec.license = "MIT"
|
9
15
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
s.email = %q{ifredwu@gmail.com}
|
15
|
-
s.extra_rdoc_files = [
|
16
|
-
"README.md"
|
17
|
-
]
|
18
|
-
s.files = [
|
19
|
-
".gitignore",
|
20
|
-
"MIT-LICENSE",
|
21
|
-
"README.md",
|
22
|
-
"Rakefile",
|
23
|
-
"VERSION",
|
24
|
-
"datamappify.gemspec",
|
25
|
-
"lib/datamappify.rb",
|
26
|
-
"lib/datamappify/associations.rb",
|
27
|
-
"lib/datamappify/collection.rb",
|
28
|
-
"lib/datamappify/fake/column.rb",
|
29
|
-
"lib/datamappify/fake/connection.rb",
|
30
|
-
"lib/datamappify/fake/index.rb",
|
31
|
-
"lib/datamappify/railtie.rb",
|
32
|
-
"lib/datamappify/resource.rb",
|
33
|
-
"lib/datamappify/schema_dumper.rb",
|
34
|
-
"lib/tasks/datamappify.rake",
|
35
|
-
"vendor/auto_migrations/MIT-LICENSE",
|
36
|
-
"vendor/auto_migrations/README",
|
37
|
-
"vendor/auto_migrations/Rakefile",
|
38
|
-
"vendor/auto_migrations/init.rb",
|
39
|
-
"vendor/auto_migrations/lib/auto_migrations.rb",
|
40
|
-
"vendor/auto_migrations/lib/tasks/auto_migrations_tasks.rake",
|
41
|
-
"vendor/auto_migrations/test/auto_migrations_test.rb"
|
42
|
-
]
|
43
|
-
s.homepage = %q{http://github.com/fredwu/datamappify}
|
44
|
-
s.rdoc_options = ["--charset=UTF-8"]
|
45
|
-
s.require_paths = ["lib", "vendor/auto_migrations/lib"]
|
46
|
-
s.rubygems_version = %q{1.3.7}
|
47
|
-
s.summary = %q{Turn ActiveRecord into DataMapper (sort of)!}
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
48
20
|
|
49
|
-
|
50
|
-
|
51
|
-
|
21
|
+
spec.add_dependency "virtus", "~> 0.5"
|
22
|
+
spec.add_dependency "activesupport", ">= 4.0.0.beta1", "< 5"
|
23
|
+
spec.add_dependency "activerecord", ">= 4.0.0.beta1", "< 5"
|
52
24
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
25
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
26
|
+
spec.add_development_dependency "rake"
|
27
|
+
spec.add_development_dependency "minitest"
|
28
|
+
spec.add_development_dependency "minitest-colorize"
|
29
|
+
spec.add_development_dependency "pry"
|
30
|
+
spec.add_development_dependency "simplecov"
|
31
|
+
spec.add_development_dependency "cane"
|
32
|
+
spec.add_development_dependency "sqlite3"
|
33
|
+
spec.add_development_dependency "database_cleaner", ">= 1.0.0.RC1", "< 2"
|
61
34
|
end
|
62
|
-
|
data/lib/datamappify.rb
CHANGED
@@ -1,18 +1,9 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require 'datamappify/fake/connection'
|
8
|
-
require 'datamappify/fake/index'
|
9
|
-
require 'datamappify/railtie'
|
10
|
-
require 'datamappify/resource'
|
11
|
-
require 'datamappify/schema_dumper'
|
1
|
+
require "active_support/inflector"
|
2
|
+
require "active_record"
|
3
|
+
require "datamappify/version"
|
4
|
+
require "datamappify/entity"
|
5
|
+
require "datamappify/data"
|
6
|
+
require "datamappify/repository"
|
12
7
|
|
13
8
|
module Datamappify
|
14
|
-
|
15
|
-
Datamappify::SchemaDumper.dump_to_file
|
16
|
-
AutoMigrations.run
|
17
|
-
end
|
18
|
-
end
|
9
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Datamappify
|
2
|
+
module Data
|
3
|
+
module AssociationMethods
|
4
|
+
def belongs_to(name, scope = nil, options = {})
|
5
|
+
build_associated_repository(name)
|
6
|
+
|
7
|
+
super(name, scope = nil, options)
|
8
|
+
end
|
9
|
+
|
10
|
+
def has_one(name, scope = nil, options = {})
|
11
|
+
build_associated_repository(name)
|
12
|
+
|
13
|
+
super(name, scope = nil, options)
|
14
|
+
end
|
15
|
+
|
16
|
+
def has_many(name, scope = nil, options = {}, &extension)
|
17
|
+
build_associated_repository(name)
|
18
|
+
|
19
|
+
super(name, scope = nil, options, &extension)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def build_associated_repository(entity_or_collection_name)
|
25
|
+
Datamappify::Repository.new(entity_or_collection_name.to_s.classify.constantize)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'virtus'
|
2
|
+
require 'datamappify/entity/association_methods'
|
3
|
+
|
4
|
+
module Datamappify
|
5
|
+
module Entity
|
6
|
+
def self.included(klass)
|
7
|
+
klass.class_eval do
|
8
|
+
include Virtus
|
9
|
+
|
10
|
+
attribute :id, Integer
|
11
|
+
|
12
|
+
extend Behaviour
|
13
|
+
extend Structure
|
14
|
+
extend AssociationMethods
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
module Behaviour
|
19
|
+
def self.extended(klass)
|
20
|
+
klass.class_eval do
|
21
|
+
include ActiveModel::Validations
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
attr_accessor :stored_validations
|
26
|
+
|
27
|
+
def validations(&block)
|
28
|
+
self.stored_validations = block
|
29
|
+
|
30
|
+
instance_eval(&block)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
module Structure
|
35
|
+
attr_accessor :stored_relationships
|
36
|
+
|
37
|
+
def relationships(&block)
|
38
|
+
self.stored_relationships = block
|
39
|
+
|
40
|
+
instance_eval(&block)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|