acts_as_paranoid_dag 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/.gitignore +17 -0
- data/.rspec +1 -0
- data/Gemfile +4 -0
- data/Guardfile +22 -0
- data/LICENSE +22 -0
- data/README.md +75 -0
- data/Rakefile +8 -0
- data/acts_as_paranoid_dag.gemspec +43 -0
- data/lib/acts_as_paranoid_dag/model_additions.rb +80 -0
- data/lib/acts_as_paranoid_dag/validation_fix.rb +31 -0
- data/lib/acts_as_paranoid_dag/version.rb +3 -0
- data/lib/acts_as_paranoid_dag.rb +11 -0
- data/spec/acts_as_paranoid_dag/model_additions_spec.rb +172 -0
- data/spec/spec_helper.rb +28 -0
- data/spec/support/schema.rb +42 -0
- metadata +243 -0
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/Gemfile
ADDED
data/Guardfile
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
guard 'rspec', :version => 2 do
|
5
|
+
watch(%r{^spec/.+_spec\.rb$})
|
6
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
7
|
+
watch('spec/spec_helper.rb') { "spec" }
|
8
|
+
|
9
|
+
# Rails example
|
10
|
+
watch(%r{^spec/.+_spec\.rb$})
|
11
|
+
watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
12
|
+
watch(%r{^app/(.*)(\.erb|\.haml)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
|
13
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
14
|
+
watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
|
15
|
+
watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
|
16
|
+
watch('spec/spec_helper.rb') { "spec" }
|
17
|
+
watch('config/routes.rb') { "spec/routing" }
|
18
|
+
watch('app/controllers/application_controller.rb') { "spec/controllers" }
|
19
|
+
# Capybara request specs
|
20
|
+
watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/requests/#{m[1]}_spec.rb" }
|
21
|
+
end
|
22
|
+
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Sebastian Fiedlschuster
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
# ActsAsParanoidDag
|
2
|
+
|
3
|
+
**acts_as_paranoid_dag** is a **ruby on rails gem** that combines the gems [acts-as-dag](https://github.com/resgraph/acts-as-dag) and [rails3_acts_as_paranoid](https://github.com/goncalossilva/rails3_acts_as_paranoid) to order model instances in a polymorphic directed acyclic graph and to be able to retrieve connections deleted in the past.
|
4
|
+
|
5
|
+
For example, I'm using this to have a user-group structure, where I can query for group memberships deleted in the past.
|
6
|
+
|
7
|
+
|
8
|
+
## Installation
|
9
|
+
|
10
|
+
Add this line to your application's Gemfile:
|
11
|
+
|
12
|
+
gem 'acts_as_paranoid_dag'
|
13
|
+
|
14
|
+
And then execute:
|
15
|
+
|
16
|
+
$ bundle
|
17
|
+
|
18
|
+
Or install it yourself as:
|
19
|
+
|
20
|
+
$ gem install acts_as_paranoid_dag
|
21
|
+
|
22
|
+
## Preparation
|
23
|
+
|
24
|
+
I'm assuming that you would like to extend the functionality of your existing DagLink model. That is, you already have a model `DagLink`.
|
25
|
+
```ruby
|
26
|
+
class DagLink < ActiveRecord::Base
|
27
|
+
acts_as_dag_links polymorphic: true
|
28
|
+
end
|
29
|
+
```
|
30
|
+
|
31
|
+
In your DagLink model, you'll need an extra column for saving the datetime of deletion.
|
32
|
+
```
|
33
|
+
$ bundle exec rails generate migration AddDeletedAtToDagLink deleted_at:datetime
|
34
|
+
$ rake db:migrate
|
35
|
+
```
|
36
|
+
|
37
|
+
Have a look at [this database schema from the gem's specs](https://github.com/fiedl/acts_as_paranoid_dag/blob/master/spec/support/schema.rb).
|
38
|
+
|
39
|
+
## Usage
|
40
|
+
|
41
|
+
In your DagLink model, just add the option `paranoid: true`.
|
42
|
+
|
43
|
+
```ruby
|
44
|
+
class DagLink < ActiveRecord::Base
|
45
|
+
acts_as_dag_links polymorphic: true, paranoid: true
|
46
|
+
end
|
47
|
+
```
|
48
|
+
|
49
|
+
Then you can retrieve links using the scopes `now`, `ìn_the_past` and `now_and_in_the_past`.
|
50
|
+
|
51
|
+
```ruby
|
52
|
+
# create link between user and group, just as in acts-as-dag
|
53
|
+
group1 = Group.create( ... )
|
54
|
+
group2 = Group.create( ... )
|
55
|
+
user = User.create( ... )
|
56
|
+
group1.child_users << user
|
57
|
+
user.links_as_child.first.destroy
|
58
|
+
group2.child_users << user
|
59
|
+
|
60
|
+
# now use the new scopes
|
61
|
+
user.links_as_child.now.count # => 1
|
62
|
+
user.links_as_child.in_the_past.count # => 1
|
63
|
+
user.links_as_child.now_and_in_the_past.count # => 2
|
64
|
+
user.links_as_child.at_time( 1.hour.ago ).count # => 0
|
65
|
+
```
|
66
|
+
|
67
|
+
You may want to have [a look at this specs](https://github.com/fiedl/acts_as_paranoid_dag/blob/master/spec/acts_as_paranoid_dag/model_additions_spec.rb).
|
68
|
+
|
69
|
+
## Contributing
|
70
|
+
|
71
|
+
1. Fork it
|
72
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
73
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
74
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
75
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/acts_as_paranoid_dag/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
|
6
|
+
gem.name = "acts_as_paranoid_dag"
|
7
|
+
|
8
|
+
gem.authors = ["Sebastian Fiedlschuster"]
|
9
|
+
gem.email = ["sebastian@fiedlschuster.de"]
|
10
|
+
|
11
|
+
gem.description = %q{Combines `acts-as-dag` and `rails3_acts_as_dag` to order model instances in a polymorphic directed acyclic graph and to be able to retrieve connections deleted in the past.}
|
12
|
+
gem.summary = gem.description
|
13
|
+
|
14
|
+
gem.homepage = "https://github.com/fiedl/acts_as_paranoid_dag"
|
15
|
+
|
16
|
+
gem.files = `git ls-files`.split($\)
|
17
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
18
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
19
|
+
|
20
|
+
gem.require_paths = ["lib"]
|
21
|
+
gem.version = ActsAsParanoidDag::VERSION
|
22
|
+
|
23
|
+
gem.add_dependency "rails", ">= 3.2"
|
24
|
+
gem.add_dependency "acts-as-dag"
|
25
|
+
gem.add_dependency "rails3_acts_as_paranoid"
|
26
|
+
|
27
|
+
gem.add_development_dependency "rake"
|
28
|
+
gem.add_development_dependency "bundler"
|
29
|
+
gem.add_development_dependency "rspec-rails", ">= 2.8.0"
|
30
|
+
gem.add_development_dependency "guard", "1.0.1"
|
31
|
+
# gem.add_development_dependency "nokogiri", ">= 1.5.0"
|
32
|
+
# gem.add_development_dependency "capybara"
|
33
|
+
gem.add_development_dependency 'rspec-rails', '2.10.0'
|
34
|
+
gem.add_development_dependency 'guard-rspec', '0.5.5'
|
35
|
+
|
36
|
+
# gem.add_development_dependency 'execjs'
|
37
|
+
# gem.add_development_dependency 'therubyracer'
|
38
|
+
|
39
|
+
gem.add_development_dependency 'sqlite3'
|
40
|
+
gem.add_development_dependency 'activerecord'
|
41
|
+
|
42
|
+
end
|
43
|
+
|
@@ -0,0 +1,80 @@
|
|
1
|
+
|
2
|
+
module ActsAsParanoidDag
|
3
|
+
module ModelAdditions
|
4
|
+
|
5
|
+
# This allows you to make your dag paranoid, meaning that connections are not destroyed,
|
6
|
+
# but instead a 'deleted_at' attribute is set.
|
7
|
+
# In your DagLink model replace
|
8
|
+
# ```
|
9
|
+
# class DagLink < ActiveRecord::Base
|
10
|
+
# acts_as_dag_links options
|
11
|
+
# end
|
12
|
+
#```
|
13
|
+
# by
|
14
|
+
# ```
|
15
|
+
# class DagLink < ActiveRecord::Base
|
16
|
+
# acts_as_dag_links options, paranoid: true
|
17
|
+
# end
|
18
|
+
#```
|
19
|
+
def acts_as_dag_links( params )
|
20
|
+
|
21
|
+
# Find out whether the dag link should have the paranoid extension.
|
22
|
+
paranoid = params[ :paranoid ]
|
23
|
+
params.delete( :paranoid )
|
24
|
+
|
25
|
+
# Call the original acts_as_dag_links method from the acts-as-dag gem.
|
26
|
+
super params
|
27
|
+
|
28
|
+
# If the dag links should be paranoid, load the corresponding extensions.
|
29
|
+
if paranoid
|
30
|
+
acts_as_paranoid
|
31
|
+
include DagLinkInstanceMethods
|
32
|
+
|
33
|
+
scope :now, where( "#{table_name}.deleted_at IS NULL" )
|
34
|
+
|
35
|
+
def now_and_in_the_past
|
36
|
+
without_paranoid_default_scope
|
37
|
+
end
|
38
|
+
|
39
|
+
def in_the_past
|
40
|
+
without_paranoid_default_scope.only_deleted
|
41
|
+
end
|
42
|
+
|
43
|
+
def at_time( time )
|
44
|
+
links = without_paranoid_default_scope
|
45
|
+
.where( "created_at <= ?", time )
|
46
|
+
links = links.where( :deleted_at => nil ) + links.where( "deleted_at >= ?", time )
|
47
|
+
links
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
module DagLinkInstanceMethods
|
55
|
+
# here the new instance methods for the DagLink model.
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
# def has_dag_links( params )
|
60
|
+
#
|
61
|
+
# paranoid = params[ :paranoid ]
|
62
|
+
# params.delete( :paranoid )
|
63
|
+
#
|
64
|
+
# dag_link_class_name = params[ :link_class_name ]
|
65
|
+
# dag_link_table_name = dag_link_class_name.constantize.table_name
|
66
|
+
#
|
67
|
+
# super params
|
68
|
+
#
|
69
|
+
# if paranoid
|
70
|
+
#
|
71
|
+
# scope :now, where( "#{dag_link_table_name}.deleted_at IS NULL" )
|
72
|
+
#
|
73
|
+
# end
|
74
|
+
#
|
75
|
+
# end
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
ActiveRecord::Base.extend ActsAsParanoidDag::ModelAdditions
|
@@ -0,0 +1,31 @@
|
|
1
|
+
|
2
|
+
# This is a fix for the interaction of the gem `rails3_acts_as_dag` and the ActiveRecord
|
3
|
+
# presence validation.
|
4
|
+
# The gem recommends to use the method `validates_uniqueness_of_without_deleted`,
|
5
|
+
# but since do not have access to the `acts-as-dag` validation declaration,
|
6
|
+
# this is not an option here.
|
7
|
+
# This, this fix adds a corresponding scope to the standard validation method.
|
8
|
+
module ActsAsParanoidValidationFix
|
9
|
+
module ActiveRecordAdditions
|
10
|
+
|
11
|
+
def validates( *attributes )
|
12
|
+
|
13
|
+
# The extension is only needed, if the instance has a :deleted_at attribute.
|
14
|
+
if self.new.respond_to?( :deleted_at )
|
15
|
+
if ( attributes[ 1 ] )
|
16
|
+
if ( attributes[ 1 ][ :uniqueness ] )
|
17
|
+
if ( attributes[ 1 ][ :uniqueness ][ :scope ] )
|
18
|
+
attributes[ 1 ][ :uniqueness ][ :scope ] += [ :deleted_at ]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
super *attributes
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
ActiveRecord::Base.extend ActsAsParanoidValidationFix::ActiveRecordAdditions
|
31
|
+
|
@@ -0,0 +1,11 @@
|
|
1
|
+
|
2
|
+
require "acts-as-dag"
|
3
|
+
require "rails3_acts_as_paranoid"
|
4
|
+
|
5
|
+
require "acts_as_paranoid_dag/version"
|
6
|
+
require "acts_as_paranoid_dag/validation_fix"
|
7
|
+
require "acts_as_paranoid_dag/model_additions"
|
8
|
+
|
9
|
+
module ActsAsParanoidDag
|
10
|
+
# Your code goes here...
|
11
|
+
end
|
@@ -0,0 +1,172 @@
|
|
1
|
+
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe ActsAsParanoidDag do
|
5
|
+
|
6
|
+
def reset_database
|
7
|
+
User.delete_all
|
8
|
+
Group.delete_all
|
9
|
+
DagLink.delete_all!
|
10
|
+
end
|
11
|
+
|
12
|
+
def create_basic_entries
|
13
|
+
@user = User.create( name: "John Doe" )
|
14
|
+
@group = Group.create( name: "Some Group" )
|
15
|
+
@sub_group = Group.create( name: "Sub Group" )
|
16
|
+
@other_group = Group.create( name: "Yet Another Group" )
|
17
|
+
end
|
18
|
+
|
19
|
+
before( :each ) do
|
20
|
+
reset_database
|
21
|
+
create_basic_entries
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "standard ActsAsDag" do
|
25
|
+
|
26
|
+
it "should allow to create the basic database entries" do
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should allow to connect the groups" do
|
30
|
+
@group.child_groups << @sub_group
|
31
|
+
@group.children.include?( @sub_group ).should be_true
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should allow to connect a user to a group" do
|
35
|
+
@sub_group.child_users << @user
|
36
|
+
@sub_group.children.include?( @user ).should be_true
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should implicitly connect also the parent group to the user" do
|
40
|
+
@group.child_groups << @sub_group
|
41
|
+
@sub_group.child_users << @user
|
42
|
+
@group.descendants.include?( @user ).should be_true
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should allow to delete a connection" do
|
46
|
+
@sub_group.child_users << @user
|
47
|
+
@sub_group.children.include?( @user ).should be_true
|
48
|
+
link = @user.links_as_child.first
|
49
|
+
link.destroyable?.should be_true
|
50
|
+
link.destroy
|
51
|
+
@user.links_as_child.count.should eq( 0 )
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
describe ActsAsParanoidDag::ModelAdditions do
|
57
|
+
|
58
|
+
describe "for DagLink" do
|
59
|
+
|
60
|
+
it "should allow to retrieve deleted connections" do
|
61
|
+
@sub_group.child_users << @user
|
62
|
+
link = @user.links_as_child.first
|
63
|
+
link.destroy
|
64
|
+
|
65
|
+
# This asks for the number of undeleted links.
|
66
|
+
@user.links_as_child.count.should eq( 0 )
|
67
|
+
|
68
|
+
# This asks for the number of all, even the deleted, links.
|
69
|
+
@user.links_as_child.with_deleted.count.should eq( 1 )
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should still allow to create a new link after deleting another" do
|
73
|
+
# This is to make sure that the deleting process does not compromise the
|
74
|
+
# link database.
|
75
|
+
|
76
|
+
@sub_group.child_users << @user
|
77
|
+
link = @user.links_as_child.first
|
78
|
+
link.destroy
|
79
|
+
|
80
|
+
@group.child_groups << @sub_group
|
81
|
+
@group.children.include?( @sub_group ).should be_true
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should still allow to recreate a link after deleting it" do
|
85
|
+
@sub_group.child_users << @user
|
86
|
+
link = @user.links_as_child.first
|
87
|
+
link.destroy
|
88
|
+
|
89
|
+
@sub_group.child_users << @user
|
90
|
+
@sub_group.children.include?( @user ).should be_true
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should allow to delete and recreate a link twice" do
|
94
|
+
@sub_group.child_users << @user
|
95
|
+
2.times do
|
96
|
+
link = @user.links_as_child.first
|
97
|
+
link.destroy
|
98
|
+
@sub_group.child_users << @user
|
99
|
+
end
|
100
|
+
|
101
|
+
@sub_group.children.include?( @user ).should be_true
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
|
108
|
+
|
109
|
+
describe "additional access methods" do
|
110
|
+
|
111
|
+
def create_links_for_one_user_and_two_groups_and_destroy_one
|
112
|
+
@group.child_users << @user
|
113
|
+
@user.links_as_child.first.destroy
|
114
|
+
@other_group.child_users << @user
|
115
|
+
end
|
116
|
+
|
117
|
+
describe "for DagLinks" do
|
118
|
+
|
119
|
+
it "should provide a method to access past and present links" do
|
120
|
+
create_links_for_one_user_and_two_groups_and_destroy_one
|
121
|
+
|
122
|
+
@user.links_as_child.now.count.should == 1
|
123
|
+
@user.links_as_child.now_and_in_the_past.count.should == 2
|
124
|
+
end
|
125
|
+
|
126
|
+
it "should provide a method to access present links" do
|
127
|
+
create_links_for_one_user_and_two_groups_and_destroy_one
|
128
|
+
|
129
|
+
@user.links_as_child.now.count.should == 1
|
130
|
+
@user.links_as_child.now.first.ancestor.should == @other_group
|
131
|
+
end
|
132
|
+
|
133
|
+
it "should provide a method to access past links" do
|
134
|
+
create_links_for_one_user_and_two_groups_and_destroy_one
|
135
|
+
|
136
|
+
@user.links_as_child.in_the_past.count.should == 1
|
137
|
+
@user.links_as_child.in_the_past.first.ancestor.should == @group
|
138
|
+
end
|
139
|
+
|
140
|
+
it "should have present links as default scope" do
|
141
|
+
create_links_for_one_user_and_two_groups_and_destroy_one
|
142
|
+
|
143
|
+
@user.links_as_child.should == @user.links_as_child.now
|
144
|
+
end
|
145
|
+
|
146
|
+
it "should provide a method to select links at a certain time" do
|
147
|
+
@group.child_users << @user
|
148
|
+
sleep 1.5
|
149
|
+
@user.links_as_child.now.count.should == 1
|
150
|
+
@user.links_as_child.at_time( 30.minutes.ago ).count.should == 0
|
151
|
+
@user.links_as_child.at_time( Time.current + 30.minutes ).count.should == 1
|
152
|
+
@user.links_as_child.first.destroy
|
153
|
+
@user.links_as_child.at_time( Time.current + 30.minutes ).count.should == 0
|
154
|
+
end
|
155
|
+
|
156
|
+
end
|
157
|
+
|
158
|
+
# describe "for the Model that has the dag links" do
|
159
|
+
#
|
160
|
+
# it "should have methods to access relatives now, and in the past" do
|
161
|
+
# create_links_for_one_user_and_two_groups_and_destroy_one
|
162
|
+
#
|
163
|
+
# @user.parents.now.count.should == 1
|
164
|
+
# @user.parents.in_the_past.count.should == 1
|
165
|
+
# @user.parents.now_and_in_the_past.cound.should == 2
|
166
|
+
# end
|
167
|
+
#
|
168
|
+
# end
|
169
|
+
|
170
|
+
end
|
171
|
+
|
172
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
|
2
|
+
# This file originally has been generated by 'rails generate rspec:install'.
|
3
|
+
|
4
|
+
ENV["RAILS_ENV"] ||= 'test'
|
5
|
+
|
6
|
+
# This is needed to have activerecord running.
|
7
|
+
require 'rails/all'
|
8
|
+
|
9
|
+
require 'rspec/rails'
|
10
|
+
require 'rspec/autorun'
|
11
|
+
|
12
|
+
require 'acts-as-dag'
|
13
|
+
require 'rails3_acts_as_paranoid'
|
14
|
+
require 'acts_as_paranoid_dag'
|
15
|
+
|
16
|
+
|
17
|
+
RSpec.configure do |config|
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
# The simulated database lives in the memory rather than in a file.
|
22
|
+
ActiveRecord::Base.establish_connection( :adapter => "sqlite3", :database => ":memory:" )
|
23
|
+
|
24
|
+
|
25
|
+
# This is the required database structure.
|
26
|
+
load File.dirname( __FILE__ ) + '/support/schema.rb'
|
27
|
+
|
28
|
+
|
@@ -0,0 +1,42 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
require 'acts_as_paranoid_dag'
|
4
|
+
|
5
|
+
# This is the required database structure.
|
6
|
+
ActiveRecord::Schema.define( :version => 1 ) do
|
7
|
+
|
8
|
+
create_table :users, force: true do |t|
|
9
|
+
t.string :name
|
10
|
+
end
|
11
|
+
|
12
|
+
create_table :groups, force: true do |t|
|
13
|
+
t.string :name
|
14
|
+
end
|
15
|
+
|
16
|
+
create_table :dag_links, force: true do |t|
|
17
|
+
t.integer :ancestor_id
|
18
|
+
t.string :ancestor_type
|
19
|
+
t.integer :descendant_id
|
20
|
+
t.string :descendant_type
|
21
|
+
t.boolean :direct
|
22
|
+
t.integer :count
|
23
|
+
t.datetime :deleted_at
|
24
|
+
t.timestamps
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
# This is how to include the functionality in the models.
|
31
|
+
class DagLink < ActiveRecord::Base
|
32
|
+
acts_as_dag_links polymorphic: true, paranoid: true
|
33
|
+
end
|
34
|
+
|
35
|
+
class User < ActiveRecord::Base
|
36
|
+
has_dag_links link_class_name: "DagLink", ancestor_class_names: %w(Group)
|
37
|
+
end
|
38
|
+
|
39
|
+
class Group < ActiveRecord::Base
|
40
|
+
has_dag_links link_class_name: "DagLink", ancestor_class_names: %w(Group), descendant_class_names: %w(Group User)
|
41
|
+
end
|
42
|
+
|
metadata
ADDED
@@ -0,0 +1,243 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: acts_as_paranoid_dag
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Sebastian Fiedlschuster
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-07-16 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rails
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '3.2'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '3.2'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: acts-as-dag
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rails3_acts_as_paranoid
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rake
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: bundler
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: rspec-rails
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: 2.8.0
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: 2.8.0
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: guard
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - '='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 1.0.1
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - '='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: 1.0.1
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: rspec-rails
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
130
|
+
requirements:
|
131
|
+
- - '='
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: 2.10.0
|
134
|
+
type: :development
|
135
|
+
prerelease: false
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
138
|
+
requirements:
|
139
|
+
- - '='
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: 2.10.0
|
142
|
+
- !ruby/object:Gem::Dependency
|
143
|
+
name: guard-rspec
|
144
|
+
requirement: !ruby/object:Gem::Requirement
|
145
|
+
none: false
|
146
|
+
requirements:
|
147
|
+
- - '='
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: 0.5.5
|
150
|
+
type: :development
|
151
|
+
prerelease: false
|
152
|
+
version_requirements: !ruby/object:Gem::Requirement
|
153
|
+
none: false
|
154
|
+
requirements:
|
155
|
+
- - '='
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: 0.5.5
|
158
|
+
- !ruby/object:Gem::Dependency
|
159
|
+
name: sqlite3
|
160
|
+
requirement: !ruby/object:Gem::Requirement
|
161
|
+
none: false
|
162
|
+
requirements:
|
163
|
+
- - ! '>='
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: '0'
|
166
|
+
type: :development
|
167
|
+
prerelease: false
|
168
|
+
version_requirements: !ruby/object:Gem::Requirement
|
169
|
+
none: false
|
170
|
+
requirements:
|
171
|
+
- - ! '>='
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
- !ruby/object:Gem::Dependency
|
175
|
+
name: activerecord
|
176
|
+
requirement: !ruby/object:Gem::Requirement
|
177
|
+
none: false
|
178
|
+
requirements:
|
179
|
+
- - ! '>='
|
180
|
+
- !ruby/object:Gem::Version
|
181
|
+
version: '0'
|
182
|
+
type: :development
|
183
|
+
prerelease: false
|
184
|
+
version_requirements: !ruby/object:Gem::Requirement
|
185
|
+
none: false
|
186
|
+
requirements:
|
187
|
+
- - ! '>='
|
188
|
+
- !ruby/object:Gem::Version
|
189
|
+
version: '0'
|
190
|
+
description: Combines `acts-as-dag` and `rails3_acts_as_dag` to order model instances
|
191
|
+
in a polymorphic directed acyclic graph and to be able to retrieve connections deleted
|
192
|
+
in the past.
|
193
|
+
email:
|
194
|
+
- sebastian@fiedlschuster.de
|
195
|
+
executables: []
|
196
|
+
extensions: []
|
197
|
+
extra_rdoc_files: []
|
198
|
+
files:
|
199
|
+
- .gitignore
|
200
|
+
- .rspec
|
201
|
+
- Gemfile
|
202
|
+
- Guardfile
|
203
|
+
- LICENSE
|
204
|
+
- README.md
|
205
|
+
- Rakefile
|
206
|
+
- acts_as_paranoid_dag.gemspec
|
207
|
+
- lib/acts_as_paranoid_dag.rb
|
208
|
+
- lib/acts_as_paranoid_dag/model_additions.rb
|
209
|
+
- lib/acts_as_paranoid_dag/validation_fix.rb
|
210
|
+
- lib/acts_as_paranoid_dag/version.rb
|
211
|
+
- spec/acts_as_paranoid_dag/model_additions_spec.rb
|
212
|
+
- spec/spec_helper.rb
|
213
|
+
- spec/support/schema.rb
|
214
|
+
homepage: https://github.com/fiedl/acts_as_paranoid_dag
|
215
|
+
licenses: []
|
216
|
+
post_install_message:
|
217
|
+
rdoc_options: []
|
218
|
+
require_paths:
|
219
|
+
- lib
|
220
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
221
|
+
none: false
|
222
|
+
requirements:
|
223
|
+
- - ! '>='
|
224
|
+
- !ruby/object:Gem::Version
|
225
|
+
version: '0'
|
226
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
227
|
+
none: false
|
228
|
+
requirements:
|
229
|
+
- - ! '>='
|
230
|
+
- !ruby/object:Gem::Version
|
231
|
+
version: '0'
|
232
|
+
requirements: []
|
233
|
+
rubyforge_project:
|
234
|
+
rubygems_version: 1.8.23
|
235
|
+
signing_key:
|
236
|
+
specification_version: 3
|
237
|
+
summary: Combines `acts-as-dag` and `rails3_acts_as_dag` to order model instances
|
238
|
+
in a polymorphic directed acyclic graph and to be able to retrieve connections deleted
|
239
|
+
in the past.
|
240
|
+
test_files:
|
241
|
+
- spec/acts_as_paranoid_dag/model_additions_spec.rb
|
242
|
+
- spec/spec_helper.rb
|
243
|
+
- spec/support/schema.rb
|