如何重新定义ruby和rails request.ip和request.remote_ip方法?

mik*_*kk1 1 ruby rack ruby-on-rails

我有一个rails应用程序,我正在尝试重载request.remote_ip和request.ip,以便使用cloudflare标头(HTTP_CF_CONNECTING_IP),如果它存在...我已经尝试过这些,但它们都没有工作:

module Rack
  class Request
    class << self
      def ip
        @ip ||= (@env['HTTP_CF_CONNECTING_IP'] || super)
      end
    end
  end
end

module ActionDispatch
  class Request < Rack::Request
    class << self
      def remote_ip
        @remote_ip ||= (@env['HTTP_CF_CONNECTING_IP'] || super)
      end
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

我不能使用额外的方法

def connecting_ip
  @env['HTTP_CF_CONNECTING_IP'] || request.remote_ip
end
Run Code Online (Sandbox Code Playgroud)

在application_controller中因为我有一些使用request.ip的其他宝石(比如设计)

谢谢!

Ale*_*yne 7

我相信request是一个例子.但是你正在定义类方法.删除class << self废话,而是重新定义实例方法.

只是注意,这听起来有点疯狂.在那里要小心.框架并不总是喜欢他们的内脏重新排列.


使用实例方法时的错误消息意味着正在进行其他操作. super调用超类实现.但是当你重新打开一个类并覆盖一些东西时,你实际上会覆盖原始的实现.由于该方法在超类中不存在,super因此不起作用.

相反,您可以声明将替换它的新方法之前使用alias保存原始实现.

module ActionDispatch
  class Request < Rack::Request
    alias :remote_ip_orig :remote_ip
    def remote_ip
      @remote_ip ||= (@env['HTTP_CF_CONNECTING_IP'] || remote_ip_orig)
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

  • 别名之间不应该有逗号:`alias:remote_ip_orig:remote_ip` (2认同)