Class: TurboBoost::Commands::Command
- Inherits:
-
Object
- Object
- TurboBoost::Commands::Command
- Includes:
- CommandCallbacks
- Defined in:
- lib/turbo_boost/commands/command.rb
Overview
TurboBoost::Commands::Command superclass. All command classes should inherit from this class.
Commands are executed via a before_action in the Rails controller lifecycle. They have access to the following 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
idi.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)
They also have access to the following class methods:
- prevent_controller_action ... Prevents the rails controller/action from running (i.e. the command handles the response entirely)
Constant Summary
Constants included from CommandCallbacks
TurboBoost::Commands::CommandCallbacks::NAME
Instance Attribute Summary collapse
-
#controller ⇒ Object
readonly
Returns the value of attribute controller.
-
#params ⇒ Object
readonly
Returns the value of attribute params.
-
#state ⇒ Object
readonly
Returns the value of attribute state.
-
#turbo_streams ⇒ Object
(also: #streams)
readonly
Returns the value of attribute turbo_streams.
Class Method Summary collapse
- .css_id_selector(id) ⇒ Object
- .prevent_controller_action(options = {}) ⇒ Object
- .preventers ⇒ Object
- .should_prevent_controller_action?(command, method_name) ⇒ Boolean
Instance Method Summary collapse
-
#convert_to_instance_variables(hash = {}) ⇒ Object
Converts a Hash to instance variables.
- #dom_id_selector ⇒ Object
- #element ⇒ Object
-
#initialize(controller, state, params = {}) ⇒ Command
constructor
A new instance of Command.
- #morph(html:, id: nil, selector: nil) ⇒ Object
-
#perform ⇒ Object
Abstract
performmethod Override in subclassed commands. -
#render(options = {}, locals = {}, &block) ⇒ Object
Same method signature as ActionView::Rendering#render (i.e. controller.view_context.render) Great for rendering partials with short-hand syntax sugar →
render "/path/to/partial". -
#resolve_state ⇒ Object
Abstract method to resolve state (default: noop) Override in subclassed commands to resolve unsigned/optimistic client state with signed/server state.
- #should_prevent_controller_action?(method_name) ⇒ Boolean
-
#transfer_instance_variables(object) ⇒ Object
Transfers all instance variables to another object.
- #turbo_stream ⇒ Object
Methods included from CommandCallbacks
#abort_handler, #aborted?, #error_handler, #errored?, #perform_with_callbacks, #performed?, #performing?, #succeeded?
Constructor Details
#initialize(controller, state, params = {}) ⇒ Command
Returns a new instance of Command.
87 88 89 90 91 92 93 |
# File 'lib/turbo_boost/commands/command.rb', line 87 def initialize(controller, state, params = {}) @controller = controller @state = state @params = params @turbo_streams = Set.new resolve_state if TurboBoost::Commands.config.resolve_state end |
Instance Attribute Details
#controller ⇒ Object (readonly)
Returns the value of attribute controller.
81 82 83 |
# File 'lib/turbo_boost/commands/command.rb', line 81 def controller @controller end |
#params ⇒ Object (readonly)
Returns the value of attribute params.
81 82 83 |
# File 'lib/turbo_boost/commands/command.rb', line 81 def params @params end |
#state ⇒ Object (readonly)
Returns the value of attribute state.
81 82 83 |
# File 'lib/turbo_boost/commands/command.rb', line 81 def state @state end |
#turbo_streams ⇒ Object (readonly) Also known as: streams
Returns the value of attribute turbo_streams.
81 82 83 |
# File 'lib/turbo_boost/commands/command.rb', line 81 def turbo_streams @turbo_streams end |
Class Method Details
.css_id_selector(id) ⇒ Object
36 37 38 39 |
# File 'lib/turbo_boost/commands/command.rb', line 36 def css_id_selector(id) return id if id.to_s.start_with?("#") "##{id}" end |
.prevent_controller_action(options = {}) ⇒ Object
45 46 47 |
# File 'lib/turbo_boost/commands/command.rb', line 45 def prevent_controller_action( = {}) preventers << .with_indifferent_access end |
.preventers ⇒ Object
41 42 43 |
# File 'lib/turbo_boost/commands/command.rb', line 41 def preventers @preventers ||= Set.new end |
.should_prevent_controller_action?(command, method_name) ⇒ Boolean
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/turbo_boost/commands/command.rb', line 49 def should_prevent_controller_action?(command, method_name) method_name = method_name.to_s match = preventers.find do || only = [:only] || [] only = [only] unless only.is_a?(Array) only.map!(&:to_s) except = [:except] || [] except = [except] unless except.is_a?(Array) except.map!(&:to_s) .blank? || only.include?(method_name) || (except.present? && except.exclude?(method_name)) end return false if match.nil? if match[:if].present? case match[:if] when Symbol then command.public_send(match[:if]) when Proc then command.instance_exec { match[:if].call command } end elsif match[:unless].present? case match[:unless] when Symbol then !command.public_send(match[:unless]) when Proc then !(command.instance_exec { match[:unless].call(command) }) end else true end end |
Instance Method Details
#convert_to_instance_variables(hash = {}) ⇒ Object
Converts a Hash to instance variables
108 109 110 111 |
# File 'lib/turbo_boost/commands/command.rb', line 108 def convert_to_instance_variables(hash = {}) return unless hash.present? hash.each { |key, value| instance_variable_set :"@#{key}", value } end |
#dom_id_selector ⇒ Object
120 121 122 |
# File 'lib/turbo_boost/commands/command.rb', line 120 def dom_id_selector(...) css_id_selector dom_id(...) end |
#element ⇒ Object
150 151 152 153 154 155 156 157 158 |
# File 'lib/turbo_boost/commands/command.rb', line 150 def element @element ||= begin attributes = params[:element_attributes].to_h TurboBoost::Commands::AttributeSet.new(attributes.merge( aria: TurboBoost::Commands::AttributeSet.new(attributes, prefix: "aria"), data: TurboBoost::Commands::AttributeSet.new(attributes, prefix: "data") )) end end |
#morph(html:, id: nil, selector: nil) ⇒ Object
145 146 147 148 |
# File 'lib/turbo_boost/commands/command.rb', line 145 def morph(html:, id: nil, selector: nil) selector ||= css_id_selector(id) turbo_streams << turbo_stream.invoke("morph", args: [html], selector: selector) end |
#perform ⇒ Object
Abstract perform method
Override in subclassed commands
103 104 105 |
# File 'lib/turbo_boost/commands/command.rb', line 103 def perform raise NotImplementedError, "#{self.class.name} must implement the `perform` method!" end |
#render(options = {}, locals = {}, &block) ⇒ Object
Same method signature as ActionView::Rendering#render (i.e. controller.view_context.render)
Great for rendering partials with short-hand syntax sugar → render "/path/to/partial"
126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/turbo_boost/commands/command.rb', line 126 def render( = {}, locals = {}, &block) return controller.view_context.render(, locals, &block) unless .is_a?(Hash) = .symbolize_keys ivars = [:assigns]&.each_with_object({}) do |(key, value), memo| memo[key] = controller.instance_variable_get(:"@#{key}") controller.instance_variable_set :"@#{key}", value end controller.view_context.render(.except(:assigns), locals, &block) ensure ivars&.each { |key, value| controller.instance_variable_set :"@#{key}", value } end |
#resolve_state ⇒ Object
Abstract method to resolve state (default: noop) Override in subclassed commands to resolve unsigned/optimistic client state with signed/server state
97 98 |
# File 'lib/turbo_boost/commands/command.rb', line 97 def resolve_state end |
#should_prevent_controller_action?(method_name) ⇒ Boolean
160 161 162 |
# File 'lib/turbo_boost/commands/command.rb', line 160 def should_prevent_controller_action?(method_name) self.class.should_prevent_controller_action? self, method_name end |
#transfer_instance_variables(object) ⇒ Object
Transfers all instance variables to another object
114 115 116 117 118 |
# File 'lib/turbo_boost/commands/command.rb', line 114 def transfer_instance_variables(object) instance_variables.each do |name| object.instance_variable_set name, instance_variable_get(name) end end |
#turbo_stream ⇒ Object
141 142 143 |
# File 'lib/turbo_boost/commands/command.rb', line 141 def turbo_stream @turbo_stream ||= Turbo::Streams::TagBuilder.new(controller.view_context) end |