Skip to content

Instantly share code, notes, and snippets.

@hopsoft
Last active June 29, 2024 07:43
Show Gist options
  • Save hopsoft/685e08a74ea9c353ea2c66038c3420df to your computer and use it in GitHub Desktop.
Save hopsoft/685e08a74ea9c353ea2c66038c3420df to your computer and use it in GitHub Desktop.
TurboBoost Command generator

TurboBoost Command Generator

Run the Generator

➜  showcase git:(main) bin/rails g turbo_boost:commands:command Example
Where is your Commands directory located? (default: app/commands)
   identical  app/commands/application_command.rb
      create  app/commands/example_command.rb

Generated ApplicationCommand

# app/commands/application_command.rb
# frozen_string_literal: true

# TurboBoost Commands are executed via a before_action in the Rails controller lifecycle.
#
# This is your ApplicationCommand superclass that holds shared Command logic.
# Additional Commands will subclass ApplicationCommand.
#
# Commands have access to the following instance methods and properties:
#
# - controller ...................... The Rails controller processing the HTTP request
# - convert_to_instance_variables ... Converts a Hash to instance variables
# - css_id_selector ................. Returns a CSS selector for an element `id` i.e. prefixes with `#`
# - dom_id .......................... The Rails dom_id helper
# - dom_id_selector ................. Returns a CSS selector for a dom_id
# - element ......................... A struct that represents the DOM element that triggered the command
# - morph ........................... Appends a Turbo Stream to morph a DOM element
# - params .......................... Commands specific params (frame_id, element, etc.)
# - render .......................... Renders Rails templates, partials, etc. (doesn't halt controller request handling)
# - renderer ........................ An ActionController::Renderer
# - state ........................... An object that stores ephemeral `state`
# - transfer_instance_variables ..... Transfers all instance variables to another object
# - turbo_stream .................... A Turbo Stream TagBuilder
# - turbo_streams ................... A list of Turbo Streams to append to the response (also aliased as streams)
#
# Commands have access to the following Class methods and properties:
#
# - prevent_controller_action ... Prevents the rails controller/action from running
#                                 i.e. the Command handles the response entirely
class ApplicationCommand < TurboBoost::Commands::Command
  # Abort a command from a before callback by invoking `throw :abort`
  # before_command { throw :abort }

  # Handle aborted commands
  #
  # NOTE: Callbacks use throw/catch to manage control flow which means
  #       this is not a real error per se, but you can intercept with rescue_from
  #
  # rescue_from TurboBoost::Commands::AbortError do |error|
  #   # do something...
  # end

  # Handle command errors
  # rescue_from TurboBoost::Commands::PerformError do |error|
  #   # do something...
  # end
end

Generated Command

# app/commands/example_command.rb
# frozen_string_literal: true

# TurboBoost Commands are executed via a before_action in the Rails controller lifecycle.
#
# Commands have access to the following instance methods and properties:
#
# - controller ...................... The Rails controller processing the HTTP request
# - convert_to_instance_variables ... Converts a Hash to instance variables
# - css_id_selector ................. Returns a CSS selector for an element `id` i.e. prefixes with `#`
# - dom_id .......................... The Rails dom_id helper
# - dom_id_selector ................. Returns a CSS selector for a dom_id
# - element ......................... A struct that represents the DOM element that triggered the command
# - morph ........................... Appends a Turbo Stream to morph a DOM element
# - params .......................... Commands specific params (frame_id, element, etc.)
# - render .......................... Renders Rails templates, partials, etc. (doesn't halt controller request handling)
# - renderer ........................ An ActionController::Renderer
# - state ........................... An object that stores ephemeral `state`
# - transfer_instance_variables ..... Transfers all instance variables to another object
# - turbo_stream .................... A Turbo Stream TagBuilder
# - turbo_streams ................... A list of Turbo Streams to append to the response (also aliased as streams)
#
# Commands have access to the following Class methods and properties:
#
# - prevent_controller_action ... Prevents the rails controller/action from running
#                                 i.e. the Command handles the response entirely
class ExampleCommand < ApplicationCommand
  # Uncomment the line below if you plan to handle the response in the Command itself
  # prevent_controller_action

  # ---
  # Commands support before/after/around filters similar to Rails controllers.
  #
  #   before_command { # logic... }
  #   before_command -> { # logic... }
  #   before_command :my_method, :another_method
  #   NOTE: You can abort Command execution in a `before_command` filter by calling `thow :abort`
  #
  #   after_command { # logic... }
  #   after_command -> { # logic... }
  #   after_command :my_method, :another_method
  #
  #   around_command { # logic... }
  #   around_command -> { # logic... }
  #   around_command :my_method, :another_method
  # ---

  # The default command method is `perform`
  #
  # It can be invoked from the client with the following markup:
  #
  #   <button data-turbo-command="ExampleCommand#perform">
  #     Invoke the perform command
  #   </button>
  #
  #   - or -
  #
  #   <button data-turbo-command="ExampleCommand">
  #     Invoke the perform command
  #   </button>
  #
  #   - or -
  #
  #   <button data-turbo-command="Example">
  #     Invoke the default command
  #   </button>
  #
  # TIP: You can wire up Commands on any HTML element.
  def perform
    # Suggested operations (pick and choose based on your use case)
    # - implement business logic
    # - update data stores
    # - modify TurboBoost state
    # - append TurboStreams to the response
    # - broadcast updates
    # - etc.
  end

  # You can also define additional custom Command methods.
  #
  # Custom methods can be invoked from the client with the following markup:
  #
  #   <button data-turbo-command="ExampleCommand#custom">
  #     Invoke the custom command
  #   </button>
  #
  #   - or -
  #
  #   <button data-turbo-command="Example#custom">
  #     Invoke the custom command
  #   </button>
  #
  # TIP: You can wire up Commands on any HTML element.
  def custom
    # logic...
  end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment