I have recently been trying to upgrade my app form Rails 2.3.8 to newly-releases Rails 3.
After going through fixing some Rails 3 RubyAMF doesn't seem to work:
>>>>>>>> RubyAMF >>>>>>>>> #<RubyAMF::Actions::PrepareAction:0x1649924> took: 0.00017 secs
The action '#<ActionDispatch::Request:0x15c0cf0>' could not be found for DaysController
/Users/tammam56/.rvm/gems/ruby-1.9.2-p0/gems/actionpack-3.0.0/lib/abstract_controller/base.rb:114:in `process'
/Users/tammam56/.rvm/gems/ruby-1.9.2-p0/gems/actionpack-3.0.0/lib/abstract_controller/rendering.rb:40:in `process'
It doesn't seem to be able to find the proper controller. Might have to do with new changes in Rails 3 Router. Do you know how to go about finding the root cause of the problem and/or trying to fix it?
I'm pasting code from RubyAMF where this is happening (Exception happens at the line: @service.process(req, res)):
#invoke the service call
def invoke
begin
# RequestStore.available_services[@amfbody.service_class_name] ||=
@service = @amfbody.service_class_name.constantize.new #handle on service
rescue Exception => e
puts e.message
puts e.backtrace
raise RUBYAMFException.new(RUBYAMFException.UNDEFINED_OBJECT_REFERENCE_ERROR, "There was an error loading the service class #{@amfbody.service_class_name}")
end
if @service.private_methods.include?(@amfbody.service_method_name.to_sym)
raise RUBYAMFExc
eption.new(RUBYAMFException.METHOD_ACCESS_ERROR, "The method {#{@amfbody.service_method_name}} in class {#{@amfbody.service_class_file_path}} is declared as private, it must be defined as public to access it.")
elsif !@service.public_methods.include?(@amfbody.service_method_name.to_sym)
raise RUBYAMFException.new(RUBYAMFException.METHOD_UNDEFINED_METHOD_ERROR, "The method {#{@amfbody.service_method_name}} in class {#{@amfbody.service_class_file_path}} is not declared.")
end
#clone the request and response and alter it for the target controller/method
req = RequestStore.rails_request.clone
res = RequestStore.rails_response.clone
#change the request controller/action targets and tell the service to process. THIS IS THE VOODOO. SWEET!
controller = @amfbody.service_class_name.gsub("Controller","").underscore
action = @amfbody.service_method_name
req.parameters['controller'] = req.request_parameters['controller'] = req.path_parameters['controller'] = controller
req.parameters['action'] = req.request_parameters['action'] = req.path_parameters['action'] = action
req.env['PATH_INFO'] = req.env['REQUEST_PATH'] = req.env['REQUEST_URI'] = "#{controller}/#{action}"
req.env['HTTP_ACCEPT'] = 'application/x-amf,' + req.env['HTTP_ACCEPT'].to_s
#set conditional helper
@service.is_amf = true
@service.is_rubyamf = true
#process the request
rubyamf_params = @service.rubyamf_params = {}
if @amfbody.value && !@amfbody.value.empty?
@amfbody.value.each_with_index do |item,i|
rubyamf_params[i] = item
end
end
# put them by default into the parameter hash if they opt for it
rubyamf_params.each{|k,v| req.parameters[k] = v} if ParameterMappings.always_add_to_params
begin
#One last update of the parameters hash, this will map custom mappings to the hash, and will override any conflicting from above
ParameterMappings.update_request_parameters(@amfbody.service_class_name, @amfbody.service_method_name, req.parameters, rubyamf_params, @amfbody.value)
rescue Exception => e
raise RUBYAMFException.new(RUBYAMFException.PARAMETER_MAPPING_ERROR, "There was an error with your parameter mappings: {#{e.message}}")
end
@service.process(req, res)
#unset conditional helper
@service.is_amf = false
@service.is_rubyamf = false
@service.rubyamf_params = rubyamf_params # add the rubyamf_args into the controller to be accessed
result = RequestStore.render_amf_results
#handle FaultObjects
if result.class.to_s == 'FaultObject' #catch returned FaultObjects - use this check so we don't have to include the fault object module
e = RUBYAMFException.new(result['code'], result['mess开发者_开发知识库age'])
e.payload = result['payload']
raise e
end
#amf3
@amfbody.results = result
if @amfbody.special_handling == 'RemotingMessage'
@wrapper = generate_acknowledge_object(@amfbody.get_meta('messageId'), @amfbody.get_meta('clientId'))
@wrapper["body"] = result
@amfbody.results = @wrapper
end
@amfbody.success! #set the success response uri flag (/onResult)
end
The best suggestion is to try rails3-amf. It currently is severely lacking in features in comparison to RubyAMF, but it does work and I'm adding new features as soon as they are requested or I have time.
精彩评论