amoeba 0.0.2 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -2,3 +2,4 @@
2
2
  .bundle
3
3
  Gemfile.lock
4
4
  pkg/*
5
+ spec/test.sqlite3
data/README.md CHANGED
@@ -1,24 +1,37 @@
1
1
  # Amoeba
2
2
 
3
- ## Overview
4
-
5
3
  Easy copying of rails associations such as `has_many`.
6
4
 
7
- I named this gem Amoeba because amoebas are (small life forms that are) good at reproducing. Their children and grandchildren also reproduce themselves quickly and easily.
5
+ ![amoebalogo](http://rocksolidwebdesign.com/wp_cms/wp-content/uploads/2012/02/amoeba_logo.jpg)
6
+
7
+ ## Background
8
+
9
+ The goal was to be able to easily and quickly reproduce ActiveRecord objects including their children, for example copying a blog post maintaining its associated tags or categories.
10
+
11
+ I named this gem "Amoeba" because amoebas are (small life forms that are) good at reproducing. Their children and grandchildren also reproduce themselves quickly and easily.
8
12
 
9
13
  ## Details
10
14
 
11
15
  An ActiveRecord extension gem to allow the duplication of associated child record objects when duplicating an active record model. This gem overrides and adds to the built in `ActiveRecord::Base#dup` method.
12
16
 
13
- Rails 3 compatible.
17
+ Rails 3.2 compatible.
14
18
 
15
19
  ## Features
16
20
 
17
- - Supports automatic recursive duplication of associated `has_one`, `has_many` and `has_and_belongs_to_many` child records.
18
- - Allows configuration of which fields to copy through a simple DSL applied to your rails models.
19
- - Supports multiple configuration styles such as inclusive, exclusive and indiscriminate (aka copy everything).
20
- - Supports preprocessing of fields to help indicate uniqueness and ensure the integrity of your data depending on your business logic needs.
21
- - Supports per instance configuration to override configuration and behavior on the fly.
21
+ - Supports the following association types
22
+ - `has_many`
23
+ - `has_one :through`
24
+ - `has_many :through`
25
+ - `has_and_belongs_to_many`
26
+ - A simple DSL for configuration of which fields to copy. The DSL can be applied to your rails models or used on the fly.
27
+ - Multiple configuration styles such as inclusive, exclusive and indiscriminate (aka copy everything).
28
+ - Supports recursive copying of child and grandchild records.
29
+ - Supports preprocessing of fields to help indicate uniqueness and ensure the integrity of your data depending on your business logic needs, e.g. prepending "Copy of " or similar text.
30
+ - Amoeba can perform the following preprocessing operations on fields of copied records
31
+ - prepend
32
+ - append
33
+ - nullify
34
+ - regex
22
35
 
23
36
  ## Installation
24
37
 
@@ -67,7 +80,7 @@ If you have some models for a blog about like this:
67
80
  belongs_to :post
68
81
  end
69
82
 
70
- Add the amoeba configuration block to your model and call the enable method to enable the copying of child records, like this:
83
+ simply add the amoeba configuration block to your model and call the enable method to enable the copying of child records, like this:
71
84
 
72
85
  class Post < ActiveRecord::Base
73
86
  has_many :comments
@@ -360,6 +373,62 @@ You may cause amoeba to keep copying down the chain as far as you like, simply a
360
373
 
361
374
  In this example, when a post is copied, amoeba will copy each all of a post's comments and will also copy each comment's ratings.
362
375
 
376
+ ### Has One Through
377
+
378
+ Using the `has_one :through` association is simple, just be sure to enable amoeba on the each model with a `has_one` association and amoeba will automatically and recursively drill down, like so:
379
+
380
+ class Supplier < ActiveRecord::Base
381
+ has_one :account
382
+ has_one :history, :through => :account
383
+
384
+ amoeba do
385
+ enable
386
+ end
387
+ end
388
+
389
+ class Account < ActiveRecord::Base
390
+ belongs_to :supplier
391
+ has_one :history
392
+
393
+ amoeba do
394
+ enable
395
+ end
396
+ end
397
+
398
+ class History < ActiveRecord::Base
399
+ belongs_to :account
400
+ end
401
+
402
+ ### Has Many Through
403
+
404
+ Copying `has_many :through` associations work automatically. They perform the copy in the same way as the `has_and_belongs_to_many` association, meaning the actual child records are not copied, but rather the associations are simply maintained. You can add some field preprocessors to the middle model if you like but this is not strictly necessary:
405
+
406
+ class Assembly < ActiveRecord::Base
407
+ has_many :manifests
408
+ has_many :parts, :through => :manifests
409
+
410
+ amoeba do
411
+ enable
412
+ end
413
+ end
414
+
415
+ class Manifest < ActiveRecord::Base
416
+ belongs_to :assembly
417
+ belongs_to :part
418
+
419
+ amoeba do
420
+ prefix :notes => "Copy of "
421
+ end
422
+ end
423
+
424
+ class Part < ActiveRecord::Base
425
+ has_many :manifests
426
+ has_many :assemblies, :through => :manifests
427
+
428
+ amoeba do
429
+ enable
430
+ end
431
+ end
363
432
 
364
433
  ### On The Fly Configuration
365
434
 
@@ -403,35 +472,35 @@ Here is a static reference to the available configuration methods, usable within
403
472
 
404
473
  `enable`
405
474
 
406
- Enables amoeba in the default style of copying all known associated child records.
475
+ Enables amoeba in the default style of copying all known associated child records. Using the enable method is only required if you wish to enable amoeba but you are not using either the `include_field` or `exclude_field` directives. If you use either inclusive or exclusive style, amoeba is automatically enabled for you, so calling `enable` would be redundant, though it won't hurt.
407
476
 
408
477
  `include_field`
409
478
 
410
- Adds a field to the list of fields which should be copied. All associations not in this list will not be copied. This method may be called multiple times, once per desired field, or you may pass an array of field names.
479
+ Adds a field to the list of fields which should be copied. All associations not in this list will not be copied. This method may be called multiple times, once per desired field, or you may pass an array of field names. Passing a single symbol will add to the list of included fields. Passing an array will empty the list and replace it with the array you pass.
411
480
 
412
481
  `exclude_field`
413
482
 
414
- Adds a field to the list of fields which should not be copied. Only the associations that are not in this list will be copied. This method may be called multiple times, once per desired field, or you may pass an array of field names.
483
+ Adds a field to the list of fields which should not be copied. Only the associations that are not in this list will be copied. This method may be called multiple times, once per desired field, or you may pass an array of field names. Passing a single symbol will add to the list of excluded fields. Passing an array will empty the list and replace it with the array you pass.
415
484
 
416
485
  `nullify`
417
486
 
418
- Adds a field to the list of non-association based fields which should be set to nil during copy. All fields in this list will be set to `nil` - note that any nullified field will be given its default value if a default value exists on this model's migration. This method may be called multiple times, once per desired field, or you may pass an array of field names.
487
+ Adds a field to the list of non-association based fields which should be set to nil during copy. All fields in this list will be set to `nil` - note that any nullified field will be given its default value if a default value exists on this model's migration. This method may be called multiple times, once per desired field, or you may pass an array of field names. Passing a single symbol will add to the list of null fields. Passing an array will empty the list and replace it with the array you pass.
419
488
 
420
489
  `prepend`
421
490
 
422
- Prefix a field with some text. This only works for string fields. Accepts a hash of fields to prepend. The keys are the field names and the values are the prefix strings. An example scenario would be to add a string such as "Copy of " to your title field. Don't forget to include extra space to the right if you want it.
491
+ Prefix a field with some text. This only works for string fields. Accepts a hash of fields to prepend. The keys are the field names and the values are the prefix strings. An example scenario would be to add a string such as "Copy of " to your title field. Don't forget to include extra space to the right if you want it. Passing a hash will add each key value pair to the list of prepend directives. If you wish to empty the list of directives, you may pass the hash inside of an array like this `[{:title => "Copy of "}]`.
423
492
 
424
493
  `append`
425
494
 
426
- Append some text to a field. This only works for string fields. Accepts a hash of fields to prepend. The keys are the field names and the values are the prefix strings. An example would be to add " (copied version)" to your description field. Don't forget to add a leading space if you want it.
495
+ Append some text to a field. This only works for string fields. Accepts a hash of fields to prepend. The keys are the field names and the values are the prefix strings. An example would be to add " (copied version)" to your description field. Don't forget to add a leading space if you want it. Passing a hash will add each key value pair to the list of prepend directives. If you wish to empty the list of directives, you may pass the hash inside of an array like this `[{:contents => " (copied version)"}]`.
427
496
 
428
497
  `regex`
429
498
 
430
- Globally search and replace the field for a given pattern. Accepts a hash of fields to run search and replace upon. The keys are the field names and the values are each a hash with information about what to find and what to replace it with. in the form of . An example would be to replace all occurrences of the word "dog" with the word "cat", the parameter hash would look like this `:contents => {:replace => /dog/, :with => "cat"}`
499
+ Globally search and replace the field for a given pattern. Accepts a hash of fields to run search and replace upon. The keys are the field names and the values are each a hash with information about what to find and what to replace it with. in the form of . An example would be to replace all occurrences of the word "dog" with the word "cat", the parameter hash would look like this `:contents => {:replace => /dog/, :with => "cat"}`. Passing a hash will add each key value pair to the list of prepend directives. If you wish to empty the list of directives, you may pass the hash inside of an array like this `[{:contents => {:replace => /dog/, :with => "cat"}]`.
431
500
 
432
501
  ## Known Limitations and Issues
433
502
 
434
- Amoeba does not yet recognize advanced versions of `has_and_belongs_to_many` such as `has_and_belongs_to_many :foo, :through => :bar`. Amoeba does not copy the actual HABMT child records but rather simply adds records to the M:M breakout table to associate the new parent copy with the same records that the original parent were associated with. In other words, it doesn't duplicate your tags or categories, but merely reassociates your parent copy with the same tags or categories that the old parent had.
503
+ Amoeba does not copy the actual HABMT child records but rather simply adds records to the M:M breakout table to associate the new parent copy with the same records that the original parent were associated with. In other words, it doesn't duplicate your tags or categories, but merely reassociates your parent copy with the same tags or categories that the old parent had.
435
504
 
436
505
  The regular expression preprocessor uses case-sensitive `String#gsub`. Given the performance decreases inherrent in using regular expressions already, the fact that character classes can essentially account for case-insensitive searches, the desire to keep the DSL simple and the general use cases for this gem, I don't see a good reason to add yet more decision based conditional syntax to accommodate using case-insensitive searches or singular replacements with `String#sub`. If you find yourself wanting either of these features, by all means fork the code base and if you like your changes, submit a pull request.
437
506
 
@@ -446,3 +515,17 @@ You may run the rspec tests like this:
446
515
  ## TODO
447
516
 
448
517
  Write more tests.... anyone?
518
+
519
+ ## License
520
+
521
+ [The BSD License](http://www.opensource.org/licenses/bsd-license.php)
522
+
523
+ Copyright (c) 2012, Vaughn Draughon
524
+ All rights reserved.
525
+
526
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
527
+
528
+ - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
529
+ - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
530
+
531
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -10,7 +10,14 @@ Gem::Specification.new do |s|
10
10
  s.homepage = "http://github.com/rocksolidwebdesign/amoeba"
11
11
  s.license = "BSD"
12
12
  s.summary = %q{Easy copying of rails models and their child associations.}
13
- s.description = %q{An extension to ActiveRecord to allow the duplication method to also copy associated children, with recursive support for nested of grandchildren. The behavior is controllable with a simple DSL both on your rails models and on the fly, i.e. per instance. Numerous configuration options and styles and preprocessing directives are included for power and flexibility. Tags: copy child associations, copy nested children, copy associated child records, deep_copy, nested copy, copy associations, copy relations, copy relationships, has_one, has_many, has_and_belongs_to_many, duplicate associations, duplicate associated records, duplicate child records, duplicate children, copy all, duplicate all.}
13
+
14
+ s.description = <<-EOF
15
+ An extension to ActiveRecord to allow the duplication method to also copy associated children, with recursive support for nested of grandchildren. The behavior is controllable with a simple DSL both on your rails models and on the fly, i.e. per instance. Numerous configuration options and styles and preprocessing directives are included for power and flexibility. Supports preprocessing of field values to prepend strings such as "Copy of " or to nullify field values - includes a regex preprocessor. Supports most association types including has_one :through and has_many :through.
16
+
17
+ Tags: copy child associations, copy nested children, copy associated child records, nested copy, copy associations, copy relations, copy relationships, duplicate associations, duplicate associated records, duplicate child records, duplicate children, copy all, duplicate all, clone child associations, clone nested children, clone associated child records, nested clone, clone associations, clone relations, clone relationships, cloning child associations, cloning nested children, cloning associated child records, deep_cloning, nested cloning, cloning associations, cloning relations, cloning relationships, cloning child associations, cloning nested children, cloning associated child records, nested cloning, cloning associations, cloning relations, cloning relationships, cloning child associations, cloning nested children, cloning associated child records, deep_cloning, nested cloning, cloning associations, cloning relations, cloning relationships, duplicate child associations, duplicate nested children, duplicate associated child records, nested duplicate, duplicate associations, duplicate relations, duplicate relationships, duplicate child associations, duplicate nested children, duplicate associated child records, deep_duplicate, nested duplicate, duplicate associations, duplicate relations, duplicate relationships, deep_copy, deep_clone, deep_cloning, deep clone, deep cloning, has_one, has_many, has_and_belongs_to_many
18
+ EOF
19
+
20
+ s.description = %q{}
14
21
 
15
22
  s.rubyforge_project = "amoeba"
16
23
 
@@ -181,13 +181,27 @@ module Amoeba
181
181
 
182
182
  case settings.macro
183
183
  when :has_one
184
+ if settings.is_a?(ActiveRecord::Reflection::ThroughReflection)
185
+ return
186
+ end
187
+
184
188
  old_obj = self.send(relation_name)
185
189
 
186
- copy_of_obj = old_obj.dup
187
- copy_of_obj[:"#{settings.foreign_key}"] = nil
190
+ if not old_obj.nil?
191
+ copy_of_obj = old_obj.dup
192
+ copy_of_obj[:"#{settings.foreign_key}"] = nil
188
193
 
189
- @result.send(:"#{relation_name}=", copy_of_obj)
194
+ @result.send(:"#{relation_name}=", copy_of_obj)
195
+ end
190
196
  when :has_many
197
+ # copying the children of the regular has many will
198
+ # effectively do what is desired anyway, the through
199
+ # association is really just for convenience usage
200
+ # on the model
201
+ if settings.is_a?(ActiveRecord::Reflection::ThroughReflection)
202
+ return
203
+ end
204
+
191
205
  self.send(relation_name).each do |old_obj|
192
206
  copy_of_obj = old_obj.dup
193
207
  copy_of_obj[:"#{settings.foreign_key}"] = nil
@@ -1,3 +1,3 @@
1
1
  module Amoeba
2
- VERSION = "0.0.2"
2
+ VERSION = "0.1.0"
3
3
  end
Binary file
@@ -13,6 +13,10 @@ describe "amoeba" do
13
13
 
14
14
  new_post = old_post.dup
15
15
 
16
+ start_account_count = Account.all.count
17
+ start_history_count = History.all.count
18
+ start_cat_count = Category.all.count
19
+ start_supercat_count = Supercat.all.count
16
20
  start_tag_count = Tag.all.count
17
21
  start_post_count = Post.all.count
18
22
  start_comment_count = Comment.all.count
@@ -23,6 +27,10 @@ describe "amoeba" do
23
27
 
24
28
  new_post.save
25
29
 
30
+ end_account_count = Account.all.count
31
+ end_history_count = History.all.count
32
+ end_cat_count = Category.all.count
33
+ end_supercat_count = Supercat.all.count
26
34
  end_tag_count = Tag.all.count
27
35
  end_post_count = Post.all.count
28
36
  end_comment_count = Comment.all.count
@@ -32,12 +40,17 @@ describe "amoeba" do
32
40
  end_posttag_count = rs["tag_count"]
33
41
 
34
42
  end_tag_count.should == start_tag_count
43
+ end_cat_count.should == start_cat_count
44
+ end_account_count.should == start_account_count * 2
45
+ end_history_count.should == start_history_count * 2
46
+ end_supercat_count.should == start_supercat_count * 2
35
47
  end_post_count.should == start_post_count * 2
36
48
  end_comment_count.should == start_comment_count * 2
37
49
  end_rating_count.should == start_rating_count * 2
38
50
  end_postconfig_count.should == start_postconfig_count * 2
39
51
  end_posttag_count.should == start_posttag_count * 2
40
52
 
53
+ new_post.supercats.map(&:ramblings).include?("Copy of zomg").should be true
41
54
  new_post.title.should == "Copy of #{old_post.title}"
42
55
  new_post.contents.should == "Here's a copy: #{old_post.contents.gsub(/dog/, 'cat')} (copied version)"
43
56
  end
@@ -6,6 +6,8 @@ t = Topic.create(:title => "Ponies", :description => "Lets talk about my ponies.
6
6
  # First Post {{{
7
7
  p1 = t.posts.create(:author => u1, :title => "My little pony", :contents => "Lorum ipsum dolor rainbow bright. I like dogs, dogs are awesome.")
8
8
  f1 = p1.create_post_config(:is_visible => true, :is_open => false, :password => 'abcdefg123')
9
+ a1 = p1.create_account(:title => "Foo")
10
+ h1 = p1.account.create_history(:some_stuff => "Bar")
9
11
  c1 = p1.comments.create(:contents => "I love it!")
10
12
  c1.ratings.create(:num_stars => 5)
11
13
  c1.ratings.create(:num_stars => 5)
@@ -22,7 +24,7 @@ c2.ratings.create(:num_stars => 1)
22
24
  c2.ratings.create(:num_stars => 1)
23
25
  c2.ratings.create(:num_stars => 2)
24
26
 
25
- c3 = p1.comments.create(:contents => "zomg kthxbbq!!11!!!1!eleven!!")
27
+ c3 = p1.comments.create(:contents => "kthxbbq!!11!!!1!eleven!!")
26
28
  c3.ratings.create(:num_stars => 0)
27
29
  c3.ratings.create(:num_stars => 0)
28
30
  c3.ratings.create(:num_stars => 1)
@@ -38,4 +40,12 @@ p1.tags << t1
38
40
  p1.tags << t2
39
41
  p1.tags << t3
40
42
  p1.save
43
+
44
+ c1 = Category.create(:title => "Umbrellas", :description => "Clown fart")
45
+ c2 = Category.create(:title => "Widgets", :description => "Humpty dumpty")
46
+ c3 = Category.create(:title => "Wombats", :description => "Slushy mushy")
47
+
48
+ Supercat.create(:post => p1, :category => c1, :ramblings => "zomg")
49
+ Supercat.create(:post => p1, :category => c2, :ramblings => "why")
50
+ Supercat.create(:post => p1, :category => c3, :ramblings => "ohnoes")
41
51
  # }}}
@@ -6,7 +6,11 @@ class Post < ActiveRecord::Base
6
6
  belongs_to :topic
7
7
  belongs_to :author, :class_name => 'User'
8
8
  has_one :post_config
9
+ has_one :account
10
+ has_one :history, :through => :account
9
11
  has_many :comments
12
+ has_many :supercats
13
+ has_many :categories, :through => :supercats
10
14
  has_and_belongs_to_many :tags
11
15
 
12
16
  amoeba do
@@ -17,6 +21,33 @@ class Post < ActiveRecord::Base
17
21
  end
18
22
  end
19
23
 
24
+ class Account < ActiveRecord::Base
25
+ belongs_to :post
26
+ has_one :history
27
+
28
+ amoeba do
29
+ enable
30
+ end
31
+ end
32
+
33
+ class History < ActiveRecord::Base
34
+ belongs_to :account
35
+ end
36
+
37
+ class Category < ActiveRecord::Base
38
+ has_many :supercats
39
+ has_many :posts, :through => :supercats
40
+ end
41
+
42
+ class Supercat < ActiveRecord::Base
43
+ belongs_to :post
44
+ belongs_to :category
45
+
46
+ amoeba do
47
+ prepend :ramblings => "Copy of "
48
+ end
49
+ end
50
+
20
51
  class PostConfig < ActiveRecord::Base
21
52
  belongs_to :post
22
53
  end
@@ -58,4 +58,28 @@ ActiveRecord::Schema.define do
58
58
  t.integer :post_id
59
59
  t.integer :tag_id
60
60
  end
61
+
62
+ create_table :categories, :force => true do |t|
63
+ t.string :title
64
+ t.string :description
65
+ end
66
+
67
+ create_table :supercats, :force => true do |t|
68
+ t.integer :post_id
69
+ t.integer :category_id
70
+ t.string :ramblings
71
+ t.timestamps
72
+ end
73
+
74
+ create_table :accounts, :force => true do |t|
75
+ t.integer :post_id
76
+ t.string :title
77
+ t.timestamps
78
+ end
79
+
80
+ create_table :histories, :force => true do |t|
81
+ t.integer :account_id
82
+ t.string :some_stuff
83
+ t.timestamps
84
+ end
61
85
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: amoeba
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2012-02-28 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
16
- requirement: &14811680 !ruby/object:Gem::Requirement
16
+ requirement: &15890320 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 1.0.0
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *14811680
24
+ version_requirements: *15890320
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rspec
27
- requirement: &14811140 !ruby/object:Gem::Requirement
27
+ requirement: &15889800 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '2.3'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *14811140
35
+ version_requirements: *15889800
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: sqlite3-ruby
38
- requirement: &14810740 !ruby/object:Gem::Requirement
38
+ requirement: &15889380 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *14810740
46
+ version_requirements: *15889380
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: activerecord
49
- requirement: &14810080 !ruby/object:Gem::Requirement
49
+ requirement: &15888640 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,16 +54,8 @@ dependencies:
54
54
  version: '3.0'
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *14810080
58
- description: ! 'An extension to ActiveRecord to allow the duplication method to also
59
- copy associated children, with recursive support for nested of grandchildren. The
60
- behavior is controllable with a simple DSL both on your rails models and on the
61
- fly, i.e. per instance. Numerous configuration options and styles and preprocessing
62
- directives are included for power and flexibility. Tags: copy child associations,
63
- copy nested children, copy associated child records, deep_copy, nested copy, copy
64
- associations, copy relations, copy relationships, has_one, has_many, has_and_belongs_to_many,
65
- duplicate associations, duplicate associated records, duplicate child records, duplicate
66
- children, copy all, duplicate all.'
57
+ version_requirements: *15888640
58
+ description: ''
67
59
  email: vaughn@rocksolidwebdesign.com
68
60
  executables: []
69
61
  extensions: []
@@ -77,12 +69,12 @@ files:
77
69
  - amoeba.gemspec
78
70
  - lib/amoeba.rb
79
71
  - lib/amoeba/version.rb
72
+ - logo.jpg
80
73
  - spec/lib/amoeba_spec.rb
81
74
  - spec/spec_helper.rb
82
75
  - spec/support/data.rb
83
76
  - spec/support/models.rb
84
77
  - spec/support/schema.rb
85
- - spec/test.sqlite3
86
78
  homepage: http://github.com/rocksolidwebdesign/amoeba
87
79
  licenses:
88
80
  - BSD
Binary file