Skip to content

Instantly share code, notes, and snippets.

@moiristo
Last active June 11, 2021 10:27
Show Gist options
  • Save moiristo/24fafe71755e6b1de9acc10a9a90e5ae to your computer and use it in GitHub Desktop.
Save moiristo/24fafe71755e6b1de9acc10a9a90e5ae to your computer and use it in GitHub Desktop.
## CREATE EXAMPLE ##
# folder: app/actions/posts
class Actions::Posts::CreatePost
include Actions::Posts::PostAction # In this scenario there is overlap between create & update, so introduce a concern
def perform!(post, author_scope:)
validate_action!(post, author_scope: author_scope)
post.assign_attributes(attributes)
post.save!
end
end
# Call
post = thread.posts.new # Note that we have scoped the entry here
action = Actions::Posts::CreatePost.new(author_id: 1, text: 'Revolution Action')
action.perform!(post, author_scope: thread.authors) # Return value is irrelevant as we built the post beforehand. Awesome!
respond_with post
# folder: app/actions/concerns/posts
module Actions::Posts::PostAction
extend ActiveSupport::Concern
include Common::Action # includes ActiveModel::Model + fail (assertion) helpers
included do
attribute :author_id, :integer
attribute :text, :string
validates :author_id, :text, presence: true
end
def validate_action!(post, author_scope:)
validate!
fail 'Author is invalid' if author_scope.where(id: author_id).none?
end
end
## UPDATE ##
# folder: app/actions/posts
class Actions::Posts::UpdatePost
include Actions::Posts::PostAction
def perform!(post, author_scope:)
post.with_lock do
validate_action!(post, author_scope: author_scope)
post.update!(attributes)
end
end
end
# Call
post = thread.posts.first!
action = Actions::Posts::UpdatePost.new(author_id: 1, text: 'Banana Plixxy Plaxxion')
action.perform!(post, author_scope: thread.authors)
respond_with post
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment