论坛首页 编程语言技术论坛

url_for in ActionMailer

浏览 2255 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-09-06  

url_for in ActionMailer

ActionMailer是Rails中发送email的一个controller。今天遇到的一个问题就是在ActionMailer controller/viewer中生成URL。我说的生成URL主要指url_for方法生成绝对路径,也就是 url_for(:only_path => false, :controller => xxx, :action => xxx)。我们都知道组成一个绝对路径需要有protocol, host, port和相对路径。在ActionMailer里面, request instance是不存在的,所以组成绝对路径的protocol, host 和 port是得不到的。

动态语言在AOP方面有着天然的优势。上面的问题可以很方面用一个around filter来解决。下面是代码片断

    module InstanceMethods
      def url_for_everywhere
        begin
          request = self.request
          ::ActionController::UrlWriter.module_eval do
            @old_default_url_options = default_url_options.clone
            default_url_options[:host] = request.host
            default_url_options[:port] = request.port unless request.port == 80
            protocol = /(.*):\/\//.match(request.protocol)[1] if request.protocol.ends_with?("://")
            default_url_options[:protocol] = protocol
          end
          yield
        ensure
          ::ActionController::UrlWriter.module_eval do
            default_url_options[:host] = @old_default_url_options[:host]
            default_url_options[:port] = @old_default_url_options[:port]
            default_url_options[:protocol] = @old_default_url_options[:protocol]
          end
        end
      end
    end

思路很简单,::ActionController::UrlWriter中有默认的default_url_options的一些参数,filter选把这些参数保存起来,尝试去取当前request对应的参数,如果有那么应用,并继续执行后面的程序(url_for就在这里),最后需要把最原始的default_url_options restore。通过这样一个around filter我们就可以透明地解决ActionMailer中url_for不能使用的问题。当然也可以把它插件化 ;)

论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics