Search code examples
ruby-on-railsruby-on-rails-5rails-api

Rails 5 API: custom hidden responder that would process value returned by the action


I have rails 5 based api app, using fast_jsonapi and after a while I observe that all most all my actions are having one common pattern

  def action_name
    @some_object.perform_action_name # this returns @some_object
    render json: ControllerNameSerializer.new(@some_object).to_h
  end

I do not wish to write the last render line here and it should work, for that I want that the returned value by the action should be processed by any hidden responder like thing, Serializer klass can be made out looking at controller name.

Perhaps this could be achieved by adding a small middleware. However at first, I find it not a good idea/practise to go for a middleware. In middleware, we do get rendered response, we need a hook prior to that.

I would imagine like

class SomeController ...
  respond_with_returned_value

  def action_name
    @some_object.perform_action_name # this returns @some_object
  end

Any suggestions?

Note, do not worry about error/failure cases, @some_object.errors could hold them and I have a mechanism to handle that separately.


Solution

  • Sketched out...

    class ApplicationController < ...
      def respond_with_returned_value
        include MyWrapperModule
      end
    ...
    end
    
    module MyWrapperModule
      def self.included(base)
        base.public_instance_methods.each do |method_name|
          original_method_name = "original_#{method_name}".to_sym
          rename method_name -> original_method_name
          define_method(method_name) { render json: send(original_method_name) }
        end
      end
    end
    

    Seems like there really should be some blessed way to do this - or like someone must have already done it.