mongoid-genesis 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +4 -0
- data/LICENSE +7 -0
- data/README.md +98 -0
- data/Rakefile +11 -0
- data/lib/mongoid/genesis/storage.rb +39 -0
- data/lib/mongoid/genesis.rb +35 -0
- data/lib/mongoid_genesis.rb +2 -0
- data/spec/mongoid/genesis_spec.rb +75 -0
- data/spec/spec_helper.rb +22 -0
- data/spec/support/models/book.rb +10 -0
- metadata +114 -0
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
Copyright (c) 2012 De Marque inc.
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
4
|
+
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
6
|
+
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
Mongoid Genesis
|
2
|
+
===============
|
3
|
+
|
4
|
+
[![Build Status](https://secure.travis-ci.org/demarque/mongoid-genesis.png?branch=master)](http://travis-ci.org/demarque/mongoid-genesis)
|
5
|
+
|
6
|
+
Mongoid Genesis will give you the ability to override data in your model
|
7
|
+
without losing the initial data.
|
8
|
+
|
9
|
+
Install
|
10
|
+
-------
|
11
|
+
|
12
|
+
```
|
13
|
+
gem install mongoid_genesis
|
14
|
+
```
|
15
|
+
|
16
|
+
Rails 3
|
17
|
+
-------
|
18
|
+
|
19
|
+
In your Gemfile:
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
gem 'mongoid_genesis'
|
23
|
+
```
|
24
|
+
|
25
|
+
Usage
|
26
|
+
-----
|
27
|
+
|
28
|
+
Mongoid Genesis is compatible with any mongoid collection or embedded object.
|
29
|
+
|
30
|
+
|
31
|
+
**Model integration**
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
class Book
|
35
|
+
include Mongoid::Document
|
36
|
+
include Mongoid::Genesis
|
37
|
+
end
|
38
|
+
```
|
39
|
+
|
40
|
+
This will create an embedded object that will store the original data.
|
41
|
+
|
42
|
+
**Basic manipulation**
|
43
|
+
|
44
|
+
```ruby
|
45
|
+
book = Book.new(:title => 'Art of war', :author => 'Sun Tzu')
|
46
|
+
#=> #<Book _id: 1, title: "Art of war", author: "Sun Tzu">
|
47
|
+
|
48
|
+
book.genesis
|
49
|
+
#=> #<BookGenesis _id: 1>
|
50
|
+
|
51
|
+
|
52
|
+
# The origin will be save
|
53
|
+
|
54
|
+
book.write_and_preserve_attribute(:author, 'Sun Zi')
|
55
|
+
#=> #<Book _id: 1, title: "Art of war", author: "Sun Zi">
|
56
|
+
|
57
|
+
book.genesis
|
58
|
+
#=> #<BookGenesis _id: 1, author: "Sun Tzu">
|
59
|
+
|
60
|
+
|
61
|
+
# The origin will not be overwritten
|
62
|
+
|
63
|
+
book.write_and_preserve_attribute(:author, 'Sun Wu')
|
64
|
+
#=> #<Book _id: 1, title: "Art of war", author: "Sun Wu">
|
65
|
+
|
66
|
+
book.genesis
|
67
|
+
#=> #<BookGenesis _id: 1, author: "Sun Tzu">
|
68
|
+
|
69
|
+
|
70
|
+
# Restoring the origin
|
71
|
+
|
72
|
+
book.restore_genesis(:author)
|
73
|
+
#=> #<Book _id: 1, title: "Art of war", author: "Sun Tzu">
|
74
|
+
|
75
|
+
book.genesis
|
76
|
+
#=> #<BookGenesis _id: 1, author: nil>
|
77
|
+
|
78
|
+
|
79
|
+
# To make some modifications on the original without losing the current state
|
80
|
+
|
81
|
+
book.write_and_preserve_attribute(:title, 'The Art of Peace')
|
82
|
+
book.reverse_genesis
|
83
|
+
|
84
|
+
#=> #<Book _id: 1, title: "The Art of War", author: "Sun Tzu">
|
85
|
+
#=> #<BookGenesis _id: 1, title: "The Art of Peace">
|
86
|
+
|
87
|
+
book.title = "The Art of War : Revisited"
|
88
|
+
book.reverse_genesis
|
89
|
+
|
90
|
+
#=> #<Book _id: 1, title: "The Art of Peace", author: "Sun Tzu">
|
91
|
+
#=> #<BookGenesis _id: 1, title: "The Art of War : Revisited">
|
92
|
+
|
93
|
+
```
|
94
|
+
|
95
|
+
Copyright
|
96
|
+
---------
|
97
|
+
|
98
|
+
Copyright (c) 2012 De Marque inc. See LICENSE for further details.
|
data/Rakefile
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
module Mongoid
|
2
|
+
module Genesis
|
3
|
+
module Storage
|
4
|
+
def field_preserved?(field_name)
|
5
|
+
self.attribute_present? field_name
|
6
|
+
end
|
7
|
+
|
8
|
+
def preserve(field_name)
|
9
|
+
self.write_attribute(field_name, self.alter.read_attribute(field_name)) if not field_preserved? field_name
|
10
|
+
end
|
11
|
+
|
12
|
+
def restore(field_name)
|
13
|
+
if field_preserved? field_name
|
14
|
+
self.alter.write_attribute(field_name, self.read_attribute(field_name))
|
15
|
+
self.remove_attribute(field_name)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def reverse
|
20
|
+
self.attributes.each do |name, value|
|
21
|
+
if not ['_id', '_type'].include? name
|
22
|
+
buffer = self.alter.read_attribute(name)
|
23
|
+
|
24
|
+
self.alter.write_attribute(name, self.read_attribute(name))
|
25
|
+
self.write_attribute(name, buffer)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def method_missing(*args, &block)
|
31
|
+
if self.alter.respond_to? args[0].to_s
|
32
|
+
self.read_attribute args[0]
|
33
|
+
else
|
34
|
+
raise NoMethodError.new("undefined local variable or method '#{args.first}' for #{self.class}")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Mongoid
|
2
|
+
module Genesis
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
def self.included(base)
|
6
|
+
Object.const_set("#{base.name}Genesis", Class.new do
|
7
|
+
include Mongoid::Document
|
8
|
+
include Mongoid::Genesis::Storage
|
9
|
+
|
10
|
+
embedded_in :alter, :class_name => base.name, :inverse_of => :genesis
|
11
|
+
end)
|
12
|
+
|
13
|
+
base.embeds_one :genesis, :class_name => "#{base.name}Genesis", :inverse_of => :alter
|
14
|
+
end
|
15
|
+
|
16
|
+
def init_genesis
|
17
|
+
self.genesis = "#{self.class.name}Genesis".constantize.new
|
18
|
+
end
|
19
|
+
|
20
|
+
def restore_genesis(field_name)
|
21
|
+
self.genesis.restore(field_name)
|
22
|
+
end
|
23
|
+
|
24
|
+
def reverse_genesis
|
25
|
+
self.genesis.reverse
|
26
|
+
end
|
27
|
+
|
28
|
+
def write_and_preserve_attribute(field_name, value)
|
29
|
+
init_genesis if not self.genesis
|
30
|
+
self.genesis.preserve field_name
|
31
|
+
|
32
|
+
self.write_attribute(field_name, value)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Mongoid::Genesis do
|
4
|
+
|
5
|
+
context 'with the book "The Art of War" written by Sun Tzu' do
|
6
|
+
let(:book) { Book.new(:title => 'The Art of War', :author => 'Sun Tzu') }
|
7
|
+
|
8
|
+
subject { book }
|
9
|
+
|
10
|
+
describe "#init_genesis" do
|
11
|
+
before { book.init_genesis }
|
12
|
+
|
13
|
+
its('genesis.title') { should be_nil }
|
14
|
+
|
15
|
+
context "genesis.pages" do
|
16
|
+
specify { expect { book.genesis.pages }.to raise_error(NoMethodError) }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "#write_and_preserve_attribute" do
|
21
|
+
context "when changing title to 'The Art of Peace'" do
|
22
|
+
before { book.write_and_preserve_attribute :title, 'The Art of Peace' }
|
23
|
+
|
24
|
+
its(:title) { should eql 'The Art of Peace' }
|
25
|
+
its('genesis.title') { should eql 'The Art of War' }
|
26
|
+
|
27
|
+
context "when changing title to 'The Art of Neutrality'" do
|
28
|
+
before { book.write_and_preserve_attribute :title, 'The Art of Neutrality' }
|
29
|
+
|
30
|
+
its(:title) { should eql 'The Art of Neutrality' }
|
31
|
+
its('genesis.title') { should eql 'The Art of War' }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "#restore_genesis" do
|
37
|
+
context "when changing title to 'The Art of Peace'" do
|
38
|
+
before { book.write_and_preserve_attribute :title, 'The Art of Peace' }
|
39
|
+
|
40
|
+
context "when restoring genesis for title" do
|
41
|
+
before { book.restore_genesis(:title) }
|
42
|
+
|
43
|
+
its(:title) { should eql 'The Art of War' }
|
44
|
+
its('genesis.title') { should be_nil }
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "#reverse_genesis" do
|
50
|
+
context "when changing title to 'The Art of Peace' and the author to 'Sun Wu'" do
|
51
|
+
before { book.write_and_preserve_attribute :title, 'The Art of Peace' }
|
52
|
+
before { book.write_and_preserve_attribute :author, 'Sun Wu' }
|
53
|
+
|
54
|
+
context "when reversing genesis" do
|
55
|
+
before { book.reverse_genesis }
|
56
|
+
|
57
|
+
its(:title) { should eql 'The Art of War' }
|
58
|
+
its(:author) { should eql 'Sun Tzu' }
|
59
|
+
|
60
|
+
context "when making raw change on title to 'The Art of War : Revisited'" do
|
61
|
+
before { book.title = 'The Art of War : Revisited' }
|
62
|
+
|
63
|
+
context "and reversing genesis again" do
|
64
|
+
before { book.reverse_genesis }
|
65
|
+
|
66
|
+
its(:title) { should eql 'The Art of Peace' }
|
67
|
+
its('genesis.title') { should eql 'The Art of War : Revisited' }
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "bundler/setup"
|
3
|
+
|
4
|
+
require 'rspec'
|
5
|
+
|
6
|
+
require 'mongoid'
|
7
|
+
require File.expand_path('../../lib/mongoid_genesis', __FILE__)
|
8
|
+
|
9
|
+
|
10
|
+
Mongoid.configure do |config|
|
11
|
+
config.master = Mongo::Connection.new.db('mongoid_genesis_test')
|
12
|
+
config.allow_dynamic_fields = false
|
13
|
+
end
|
14
|
+
|
15
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
16
|
+
|
17
|
+
RSpec.configure do |config|
|
18
|
+
config.mock_with :rspec
|
19
|
+
config.after :each do
|
20
|
+
Mongoid.master.collections.reject { |c| c.name =~ /^system\./ }.each(&:drop)
|
21
|
+
end
|
22
|
+
end
|
metadata
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mongoid-genesis
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Sebastien Rosa
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-03-23 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: mongoid
|
16
|
+
requirement: &2152274840 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '2.0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *2152274840
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: bson_ext
|
27
|
+
requirement: &2152273320 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ~>
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '1.6'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *2152273320
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rake
|
38
|
+
requirement: &2152272120 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 0.8.7
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *2152272120
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rspec
|
49
|
+
requirement: &2152270580 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '2.0'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *2152270580
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: metrical
|
60
|
+
requirement: &2152269060 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: 0.1.0
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *2152269060
|
69
|
+
description: Mongoid Genesis will give you the ability to override attribute values
|
70
|
+
without losing the original one.
|
71
|
+
email:
|
72
|
+
- sebastien@demarque.com
|
73
|
+
executables: []
|
74
|
+
extensions: []
|
75
|
+
extra_rdoc_files:
|
76
|
+
- LICENSE
|
77
|
+
- README.md
|
78
|
+
files:
|
79
|
+
- lib/mongoid/genesis/storage.rb
|
80
|
+
- lib/mongoid/genesis.rb
|
81
|
+
- lib/mongoid_genesis.rb
|
82
|
+
- spec/mongoid/genesis_spec.rb
|
83
|
+
- spec/spec_helper.rb
|
84
|
+
- spec/support/models/book.rb
|
85
|
+
- LICENSE
|
86
|
+
- README.md
|
87
|
+
- Rakefile
|
88
|
+
- Gemfile
|
89
|
+
homepage: https://github.com/demarque/mongoid-genesis
|
90
|
+
licenses:
|
91
|
+
- MIT
|
92
|
+
post_install_message:
|
93
|
+
rdoc_options: []
|
94
|
+
require_paths:
|
95
|
+
- lib
|
96
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
103
|
+
none: false
|
104
|
+
requirements:
|
105
|
+
- - ! '>='
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: '0'
|
108
|
+
requirements: []
|
109
|
+
rubyforge_project: mongoid-genesis
|
110
|
+
rubygems_version: 1.8.17
|
111
|
+
signing_key:
|
112
|
+
specification_version: 3
|
113
|
+
summary: Preserve the original data of a model.
|
114
|
+
test_files: []
|