class StimulusReflex::Reflex

Attributes

action_name[R]
broadcaster[R]
cable_ready[R]
channel[R]
client_attributes[R]
element[R]
logger[R]
method_name[R]
selectors[R]
url[R]

Public Class Methods

new(channel, url: nil, element: nil, selectors: [], method_name: nil, params: {}, client_attributes: {}) click to toggle source
# File lib/stimulus_reflex/reflex.rb, line 19
  def initialize(channel, url: nil, element: nil, selectors: [], method_name: nil, params: {}, client_attributes: {})
    if is_a? CableReady::Broadcaster
      message = <<~MSG

        #{self.class.name} includes CableReady::Broadcaster, and you need to remove it.
        Reflexes have their own CableReady interface. You can just assume that it's present.
        See https://docs.stimulusreflex.com/rtfm/cableready#using-cableready-inside-a-reflex-action for more details.

      MSG
      raise TypeError.new(message.strip)
    end

    @channel = channel
    @url = url
    @element = element
    @selectors = selectors
    @method_name = method_name
    @params = params
    @broadcaster = StimulusReflex::PageBroadcaster.new(self)
    @logger = StimulusReflex::Logger.new(self)
    @client_attributes = ClientAttributes.new(client_attributes)
    @cable_ready = StimulusReflex::CableReadyChannels.new(stream_name)
    self.params
  end

Public Instance Methods

controller() click to toggle source
# File lib/stimulus_reflex/reflex.rb, line 97
def controller
  @controller ||= begin
    controller_class.new.tap do |c|
      c.instance_variable_set :"@stimulus_reflex", true
      instance_variables.each { |name| c.instance_variable_set name, instance_variable_get(name) }
      c.set_request! request
      c.set_response! controller_class.make_response!(request)
    end
  end
end
default_reflex() click to toggle source
# File lib/stimulus_reflex/reflex.rb, line 124
def default_reflex
  # noop default reflex to force page reloads
end
dom_id(record_or_class, prefix = nil) click to toggle source
# File lib/stimulus_reflex/reflex.rb, line 132
def dom_id(record_or_class, prefix = nil)
  "#" + ActionView::RecordIdentifier.dom_id(record_or_class, prefix).to_s
end
halted?() click to toggle source

Indicates if the callback chain was halted via a throw(:abort) in a before_reflex callback. SEE: api.rubyonrails.org/classes/ActiveSupport/Callbacks.html IMPORTANT: The reflex will not re-render the page if the callback chain is halted

# File lib/stimulus_reflex/reflex.rb, line 120
def halted?
  !!@halted
end
morph(selectors, html = "") click to toggle source
# File lib/stimulus_reflex/reflex.rb, line 83
def morph(selectors, html = "")
  case selectors
  when :page
    raise StandardError.new("Cannot call :page morph after :#{broadcaster.to_sym} morph") unless broadcaster.page?
  when :nothing
    raise StandardError.new("Cannot call :nothing morph after :selector morph") if broadcaster.selector?
    @broadcaster = StimulusReflex::NothingBroadcaster.new(self) unless broadcaster.nothing?
  else
    raise StandardError.new("Cannot call :selector morph after :nothing morph") if broadcaster.nothing?
    @broadcaster = StimulusReflex::SelectorBroadcaster.new(self) unless broadcaster.selector?
    broadcaster.append_morph(selectors, html)
  end
end
params() click to toggle source
# File lib/stimulus_reflex/reflex.rb, line 128
def params
  @_params ||= ActionController::Parameters.new(request.parameters)
end
process(name, *args) click to toggle source
# File lib/stimulus_reflex/reflex.rb, line 108
def process(name, *args)
  reflex_invoked = false
  result = run_callbacks(:process) {
    public_send(name, *args).tap { reflex_invoked = true }
  }
  @halted ||= result == false && !reflex_invoked
  result
end
request() click to toggle source
# File lib/stimulus_reflex/reflex.rb, line 44
def request
  @request ||= begin
    uri = URI.parse(url)
    path = ActionDispatch::Journey::Router::Utils.normalize_path(uri.path)
    query_hash = Rack::Utils.parse_nested_query(uri.query)
    mock_env = Rack::MockRequest.env_for(uri.to_s)

    mock_env.merge!(
      "rack.request.query_hash" => query_hash,
      "rack.request.query_string" => uri.query,
      "ORIGINAL_SCRIPT_NAME" => "",
      "ORIGINAL_FULLPATH" => path,
      Rack::SCRIPT_NAME => "",
      Rack::PATH_INFO => path,
      Rack::REQUEST_PATH => path,
      Rack::QUERY_STRING => uri.query
    )

    env = connection.env.merge(mock_env)

    middleware = StimulusReflex.config.middleware

    if middleware.any?
      stack = middleware.build(Rails.application.routes)
      stack.call(env)
    end

    req = ActionDispatch::Request.new(env)

    path_params = Rails.application.routes.recognize_path_with_request(req, url, req.env[:extras] || {})
    path_params[:controller] = path_params[:controller].force_encoding("UTF-8")
    path_params[:action] = path_params[:action].force_encoding("UTF-8")

    req.env.merge(ActionDispatch::Http::Parameters::PARAMETERS_KEY => path_params)
    req.env["action_dispatch.request.parameters"] = req.parameters.merge(@params)
    req.tap { |r| r.session.send :load! }
  end
end