[Awesome Ruby Gem] Use amoeba gem to clone active_record objects including associations and several operations
amoeba
Easy cloning of active_record objects including associations and several operations under associations and attributes.
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.
Features
-
Supports the following association types
-
has_many
-
has_one :through
-
has_many :through
-
has_and_belongs_to_many
-
-
A simple DSL for configuration of which fields to copy. The DSL can be applied to your rails models or used on the fly.
-
Supports STI (Single Table Inheritance) children inheriting their parent amoeba settings.
-
Multiple configuration styles such as inclusive, exclusive and indiscriminate (aka copy everything).
-
Supports cloning of the children of Many-to-Many records or merely maintaining original associations
-
Supports automatic drill-down i.e. recursive copying of child and grandchild records.
-
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.
-
Supports preprocessing of fields with custom lambda blocks so you can do basically whatever you want if, for example, you need some custom logic while making copies.
-
Amoeba can perform the following preprocessing operations on fields of copied records
-
set
-
prepend
-
append
-
nullify
-
customize
-
regex
-
Installation
You can install it as a gem:
1 | gem install amoeba |
or add it into a Gemfile (Bundler):
1 | # Gemfile |
Then, run bundle install
.
1 | bundle install |
Usages
Configure your models with one of the styles below and then just run the amoeba_dup
method on your model where you would run the dup method normally:
Indiscriminate Style
This is the most basic usage case and will simply enable the copying of any known associations.
If you have some models for a blog about like this:
1 | class Post < ActiveRecord::Base |
simply add the amoeba configuration block to your model and call the enable method to enable the copying of child records, like this:
1 | class Post < ActiveRecord::Base |
Child records will be automatically copied when you run the amoeba_dup method.
Inclusive Style
If you only want some of the associations copied but not others, you may use the inclusive style:
1 | class Post < ActiveRecord::Base |
Using the inclusive style within the amoeba block actually implies that you wish to enable amoeba, so there is no need to run the enable method, though it won’t hurt either:
1 | class Post < ActiveRecord::Base |
You may also specify fields to be copied by passing an array. If you call the include_association with a single value, it will be appended to the list of already included fields. If you pass an array, your array will overwrite the original values.
1 | class Post < ActiveRecord::Base |
These examples will copy the post’s tags and authors but not its comments.
The inclusive style, when used, will automatically disable any other style that was previously selected.
Exclusive Style
If you have more fields to include than to exclude, you may wish to shorten the amount of typing and reading you need to do by using the exclusive style. All fields that are not explicitly excluded will be copied:
1 | class Post < ActiveRecord::Base |
This example does the same thing as the inclusive style example, it will copy the post’s tags and authors but not its comments. As with inclusive style, there is no need to explicitly enable amoeba when specifying fields to exclude.
The exclusive style, when used, will automatically disable any other style that was previously selected, so if you selected include fields, and then you choose some exclude fields, the exclude_association method will disable the previously selected inclusive style and wipe out any corresponding include fields.
Conditions
Also if you need to path extra condition for include or exclude relationship you can path method name to :if option.
1 | class Post < ActiveRecord::Base |
After call Post.first.amoeba_dup
if likes is larger 15 than all comments will be duplicated too, but in another situation - no relations will be cloned. Same behavior will be for exclude_association
.
Be aware! If you wrote:
1 | class Post < ActiveRecord::Base |
inclusion strategy will be chosen regardless of the result of popular?
method call (the same for reverse situation).
See GitHub - amoeba-rb/amoeba: A ruby gem to allow the copying of ActiveRecord objects and their associated children, configurable with a DSL on the model - https://github.com/amoeba-rb/amoeba to learn more Usages.
References
[2] amoeba | RubyGems.org | your community gem host - https://rubygems.org/gems/amoeba/
[3] GitHub - clowne-rb/clowne: A flexible gem for cloning models - https://github.com/clowne-rb/clowne