Notice: after_persist
supported only with active_record
adapter.
The special mechanism for transformation of cloned record. In contradistinction to finalize
executes with a saved record. This type of callbacks provides a default mapper:
parameter which contains a relation between origin and cloned objects.
after_persist
helps to restore broken relationships while cloning associations and implement some logic with already persisted clone record. (Inspired by issues#19)
Examples:
class User < ActiveRecord::Base
# create_table :users do |t|
# t.string :login
# t.integer :bio_id
# end
has_many :posts # all user's posts including BIO
belongs_to :bio, class_name: "Post"
end
class Post < ActiveRecord::Base
# create_table :posts do |t|
# t.integer :user_id
# end
end
class UserCloner < Clowne::Cloner
include_association :posts, params: true
after_persist do |origin, clone, mapper:, **|
cloned_bio = mapper.clone_of(origin.bio)
clone.update(bio_id: cloned_bio.id)
end
end
class PostCloner < Clowne::Cloner
after_persist do |_, clone, run_job:, **|
PostBackgroundJob.perform_async(clone.id) if run_job
end
end
Notice: See more about mapper:
here
.
after_persist
runs when you call Operation#persist
(or Operation#persist!
)
# prepare data
user = User.create
posts = Array.new(3) { Post.create(user: user) }
bio = posts.sample
user.update(bio_id: bio.id)
operation = UserCloner.call(user, run_job: true)
# => <#Clowne::Utils::Operation ...>
clone = operation.to_record
# => <#User id: nil, ...>
# we copy all user attributes including bio_id
# but this is wrong because bio refers to the source user's bio
# and we can fix it using after_persist when posts already saved
clone.bio_id == bio.id
# => true
# save clone and run after_persist callbacks
operation.persit
clone.bio_id == bio.id
# => false
clone.posts.pluck(:id).include?(clone.bio_id)
# => true
Notice: be careful while using after_persist feature! If you clone a fat record (with a lot of associations) and will implement complex logic inside after_persist
callback, it may affect your system.