clowne-rb/clowne

View on GitHub
docs/operation.md

Summary

Maintainability
Test Coverage
# Operation

Since version 1.0 Clowne has been returning specific result object instead of a raw cloned object. It has allowed unifying interface between adapters and has opened an opportunity to implement new features. We call this object `Operation`.

An instance of `Operation` has a very clear interface:

```ruby
class User < ActiveRecord::Base; end

class UserCloner < Clowne::Cloner
  nullify :email

  after_persist do |_origin, cloned, **|
    cloned.update(email: "evl-#{cloned.id}.ms")
  end
end

user = User.create(email: "evl.ms")
# => <#User id: 1, email: 'evl.ms', ...>

operation = UserCloner.call(user)

# Return resulted (non saved) object:
operation.to_record
# => <#User id: nil, email: nil, ...>

# Save cloned object and call after_persist callbacks:
operation.persist # or operation.persist!
# => true

operation.to_record
# => <#User id: 2, email: 'evl-2.ms', ...>

# Call only after_persist callbacks:
user2 = operation.to_record
# => <#User id: 2, email: 'evl-2.ms', ...>
user2.update(email: "admin@example.com")
# => <#User id: 2, email: 'admin@example.com' ...>
operation.run_after_persist
# => <#User id: 2, email: 'evl-2.ms', ...>
```

The last example is weird, but it can be helpful when you need to execute `save` (or `save!`) separately from `after_persist` callbacks:

```ruby
operation = UserClone.call(user)

# Wrap main cloning into the transaction
ActiveRecord::Base.transaction do
  operation.to_record.save!
end

# And after that execute after_persist without transaction
operation.run_after_persist
```