如何在 ActiveJob 作业中使用 url_for / polymorphic_url?
How can I use url_for / polymorphic_url from an ActiveJob job?
我有一个从 ActiveJob 作业内部调用的通知服务(使用 delayed_job 后端)。每个通知的主题是一个模型实例,可以是几个不同的 classes 中的任何一个。为了收件人的方便,我需要在该对象的视图中包含一个 link。
这不起作用,因为 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
似乎想要 controller/action 规范,而不是模型。
在邮件程序中,我可以使用 url_for(object)
,无论是什么型号,它都能正常工作 class。那么我如何访问作业中的多态 url 助手?
经过更多思考(并通读 Rails 源代码)后,我想出了一个解决方案。我在 app/jobs/application_job.rb
中创建了一个特定于应用程序的基础 class 以从以下位置继承作业:
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 这样:
class NotificationJob < ApplicationJob
def perform(object, message)
NotificationService.send(url_for(object), message)
end
end
我惊讶地发现 Rails.application.routes.url_helpers.url_for
的行为作为包含的实例方法与作为单例的行为如此不同,但对源代码的检查证实了这一点。
有没有更好的解决方案?
@inopinatus 的回答很好,但我在 Rails 4 的配置中被绊倒了。
config.active_job.default_url_options = { host: "example.com" }
在初始化第一个 ActiveJob 时导致"NoMethodError: undefined method `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' }
我有一个从 ActiveJob 作业内部调用的通知服务(使用 delayed_job 后端)。每个通知的主题是一个模型实例,可以是几个不同的 classes 中的任何一个。为了收件人的方便,我需要在该对象的视图中包含一个 link。
这不起作用,因为 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
似乎想要 controller/action 规范,而不是模型。
在邮件程序中,我可以使用 url_for(object)
,无论是什么型号,它都能正常工作 class。那么我如何访问作业中的多态 url 助手?
经过更多思考(并通读 Rails 源代码)后,我想出了一个解决方案。我在 app/jobs/application_job.rb
中创建了一个特定于应用程序的基础 class 以从以下位置继承作业:
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 这样:
class NotificationJob < ApplicationJob
def perform(object, message)
NotificationService.send(url_for(object), message)
end
end
我惊讶地发现 Rails.application.routes.url_helpers.url_for
的行为作为包含的实例方法与作为单例的行为如此不同,但对源代码的检查证实了这一点。
有没有更好的解决方案?
@inopinatus 的回答很好,但我在 Rails 4 的配置中被绊倒了。
config.active_job.default_url_options = { host: "example.com" }
在初始化第一个 ActiveJob 时导致"NoMethodError: undefined method `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' }