如何从ActiveJob作业中使用url_for / polymorphic_url?

时间:2015-09-08 01:13:25

标签: ruby-on-rails rails-activejob

我有一个通知服务,我从ActiveJob作业内部调用(使用delayed_job后端)。每个通知的主题是一个模型实例,可以是几个不同类中的任何一个。为了方便收件人,我需要包含指向该对象视图的链接。

这不起作用,因为url_for不是作业上下文中可用的方法:

class NotificationJob < ActiveJob::Base
  def perform(object, message)
    NotificationService.send(url_for(object), message)
  end
end

在此代码的先前且更有限的版本中,我使用了Rails.application.routes.url_helpers.model_name_url(object),但这是特定于模型的。似乎Rails.application.routes.url_for想要一个控制器/动作规范,而不是模型。

在邮寄者中,我可以使用url_for(object),无论模型类是什么,它都是正确的。那么我如何在作业中访问多态url助手呢?

2 个答案:

答案 0 :(得分:8)

@ inopinatus的答案很棒,但我在Rails 4中遇到了配置。

config.active_job.default_url_options = { host: "example.com" }

初始化第一个ActiveJob时出现“NoMethodError:未定义的方法`default_url_options ='for ActiveJob :: Base:Class”。

Rails 4 configuration guide描述了使用config.x…进行自定义属性。我需要做出以下调整:

def default_url_options
  Rails.configuration.x.application_job.default_url_options
end

config.x.application_job.default_url_options = { host: 'example.com' }

答案 1 :(得分:4)

经过一番思考(并阅读Rails源代码)后,我想出了一个解决方案。我在app/jobs/application_job.rb创建了一个特定于应用程序的基类来继承以下作业:

class ApplicationJob < ActiveJob::Base
  include Rails.application.routes.url_helpers

  protected
  def default_url_options
    Rails.application.config.active_job.default_url_options
  end
end

将必要的内容添加到config/application.rb

config.active_job.default_url_options = { host: "example.com" }

并改变了原来的课程:

class NotificationJob < ApplicationJob
  def perform(object, message)
    NotificationService.send(url_for(object), message)
  end
end

我很惊讶地发现Rails.application.routes.url_helpers.url_for的行为与包含的实例方法不同,而不是单例,但是对源的检查证实了它。

有更好的解决方案吗?