-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
A different take on the Interactor pattern
The Interactor pattern is quite simple, but trying to use it leaves two issues unresolved: the verbose passing of variables, either with context or between methods; and the structure of the actions we're trying to encapsulate, most which have a somewhat hidden lock/release mechanism. Re-implementing the Interactor pattern locally gives the opportunity to address some of these issues, but also to go completely off-the-rails! This is really another example of what the end-result could look like, which has some good and bad attributes over vanilla Interactors.
- Loading branch information
Ben Thorner
committed
Mar 27, 2019
1 parent
64f7511
commit 9f6e34b
Showing
5 changed files
with
203 additions
and
72 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
# frozen_string_literal: true | ||
|
||
require "beneractors/beneractor" | ||
|
||
module Images | ||
class CreateActor < Beneractors::Beneractor | ||
def pre_op | ||
export :edition, Edition.find_current(document: document) | ||
edition.lock! | ||
|
||
export :issues, ::Requirements::ImageUploadChecker.new(image).issues | ||
abort!(:issues) if issues.any? | ||
end | ||
|
||
def op | ||
export :image_revision, ImageUploadService | ||
.new(image, edition.revision) | ||
.call(user) | ||
|
||
updater = Versioning::RevisionUpdater.new(edition.revision, user) | ||
updater.update_image(image_revision) | ||
|
||
edition.assign_revision(updater.next_revision, user) | ||
edition.save! | ||
end | ||
|
||
def post_op | ||
PreviewService.new(edition).try_create_preview | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
# frozen_string_literal: true | ||
|
||
require "beneractors/beneractor" | ||
|
||
module Images | ||
class UpdateActor < Beneractors::Beneractor | ||
def pre_op | ||
export :edition, Edition.find_current(document: document) | ||
edition.lock! | ||
|
||
export :image_revision, edition.image_revisions.find_by!(image_id: image_id) | ||
image_updater = Versioning::ImageRevisionUpdater.new(image_revision, user) | ||
|
||
image_updater.assign(update_params) | ||
export :next_image_revision, image_updater.next_revision | ||
|
||
export :issues, Requirements::ImageRevisionChecker.new(next_image_revision) | ||
.pre_preview_metadata_issues | ||
|
||
abort!(:issues) if issues.any? | ||
|
||
export :updater, Versioning::RevisionUpdater.new(edition.revision, user) | ||
updater.update_image(next_image_revision, lead_image == "on") | ||
abort! unless updater.changed? | ||
end | ||
|
||
def op | ||
export :timeline_entry_type, | ||
if updater.selected_lead_image? | ||
:lead_image_selected | ||
elsif updater.removed_lead_image? | ||
:lead_image_removed | ||
else | ||
:image_updated | ||
end | ||
|
||
TimelineEntry.create_for_revision( | ||
entry_type: timeline_entry_type, | ||
edition: edition, | ||
) | ||
|
||
edition.assign_revision(updater.next_revision, user) | ||
edition.save! | ||
success!(timeline_entry_type) | ||
end | ||
|
||
def post_op | ||
PreviewService.new(edition).try_create_preview | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
# frozen_string_literal: true | ||
|
||
require "beneractors/context" | ||
|
||
module Beneractors | ||
class Beneractor | ||
attr_reader :context | ||
delegate_missing_to :@context | ||
|
||
def self.call(context = {}) | ||
context = Context.new(context) | ||
|
||
ActiveRecord::Base.transaction do | ||
new(context).call | ||
context | ||
end | ||
rescue Context::FailError | ||
context | ||
end | ||
|
||
private_class_method :new | ||
|
||
def export(name, value) | ||
context[name] = value | ||
end | ||
|
||
def initialize(context) | ||
@context = context | ||
end | ||
|
||
def call | ||
pre_op | ||
op | ||
post_op | ||
end | ||
|
||
def pre_op | ||
context.fail! | ||
end | ||
|
||
def op | ||
raise "not implemented" | ||
end | ||
|
||
def post_op; end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# frozen_string_literal: true | ||
|
||
module Beneractors | ||
class Context < OpenStruct | ||
class FailError < RuntimeError; end | ||
|
||
def abort!(failure_type) | ||
@failure_type = failure_type | ||
@success_type = false | ||
raise FailError | ||
end | ||
|
||
def success!(success_type = true) | ||
@success_type = success_type | ||
@failure_type = false | ||
end | ||
|
||
def success?(success_type = true) | ||
@success_type == success_type | ||
end | ||
|
||
def aborted?(failure_type = true) | ||
@failure_type == failure_type | ||
end | ||
end | ||
end |