Last active
June 22, 2017 17:40
-
-
Save catmando/3a37098ba8a61cdd208e09e0a9051f5f to your computer and use it in GitHub Desktop.
hyper operation Controller Operation experimental patch
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
# app/hyperloop/operations/controller_op.rb | |
# make sure to also require 'operations/controller_op' | |
# at the *END* of config/initializers/hyperloop.rb | |
module Hyperloop | |
# monkey patch HyperloopController to pass controller instance from controller method to ServerOp | |
Engine.routes.append do | |
class HyperloopController < ::ApplicationController | |
def execute_remote | |
parsed_params = JSON.parse(params[:json]).symbolize_keys | |
render ServerOp.run_from_client( | |
:acting_user, | |
self, # this gets added | |
parsed_params[:operation], | |
parsed_params[:params].merge(acting_user: acting_user) | |
) | |
end | |
def execute_remote_api | |
params.require(:params).permit! | |
parsed_params = params[:params].to_h.symbolize_keys | |
raise AccessViolation unless parsed_params[:authorization] | |
# likewise add self here as second param | |
render ServerOp.run_from_client(:authorization, self, params[:operation], parsed_params) | |
end | |
end | |
end unless RUBY_ENGINE == 'opal' | |
# monkey patch run_from_client so it accepts controller | |
class ServerOp < Operation | |
def self.run_from_client(security_param, controller, operation, params) | |
operation.constantize.class_eval do | |
# if the params expect a controller then merge it in | |
# and if we are passing in a controller then we can ignore the security param | |
if _Railway.params_wrapper.method_defined?(:controller) | |
params[:controller] = controller | |
# but if we are not passing a controller, then we must have th security param defined | |
elsif !_Railway.params_wrapper.method_defined?(security_param) | |
raise AccessViolation | |
end | |
run(params) | |
.then { |r| return { json: { response: serialize_response(r) } } } | |
.fail { |e| return { json: { error: e}, status: 500 } } | |
end | |
rescue Exception => e | |
{ json: {error: e}, status: 500 } | |
end | |
end unless RUBY_ENGINE == 'opal' | |
# at this point you can add a controller param to a ServerOp and you will be able to use it | |
# but to make things nice we will define a subclass that already takes the controller | |
# and then make the Operation act like a Controller delegate | |
class ControllerOp < ServerOp; end | |
class ControllerOp < ServerOp | |
param :controller | |
alias pre_controller_op_method_missing method_missing | |
def method_missing(name, *args, &block) | |
if params.controller.respond_to? name | |
params.controller.send(name, *args, &block) | |
else | |
pre_controller_op_method_missing(name, *args, &block) | |
end | |
end | |
end unless RUBY_ENGINE == 'opal' | |
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
# example Operation using ControllerOp subclass | |
require 'operations/controller_op' | |
class GetSessionId < Hyperloop::ControllerOp | |
step { session.delete 'hyperloop-dummy-init' unless session.id } | |
step { session.id } | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment