我有一种情况,我想在数据库中创建记录后向第三方 API(url 缩短服务)发出请求(更新存储短 url 的表中的列),以便解耦来自模型的 API 请求,我设置了一个 ActiveRecord Observer,它在每次创建记录时启动,使用 after_create
回调 Hook ,这里是相关代码:
class Article < ActiveRecord::Base
has_many :comments
end
class ArticleObserver < ActiveRecord::Observer
def after_create(model)
url = article_url(model)
# Make api request...
end
end
上面代码中的问题是 article_url
因为 Rails Routes 在 Model 或 ModelObservers 中都不可用,与 ActionMailer 相同(类似的问题存在于 Mails 中,如果我们需要放置一个 URL,我们必须配置“ActionMailer::default_options_url”)。理论上访问模型中的路由/请求对象被认为是一个糟糕的设计。为了避免上述问题,我可以按照以下 URL 中的描述包含 url_helpers
模块:
http://slaive-prog.tumblr.com/post/7618787555/using-routes-in-your-model-in-rails-3-0-x
但在我看来这不是一个干净的解决方案,有没有人对这个问题有任何指示或关于应该如何完成的任何建议?
提前致谢。
最佳答案
我绝对不会让你的模型知道你的路线。相反,在您的 Article
类中添加类似 attr_accessor :unshortened_url
的内容。在您的 Controller 中设置该字段,然后从您的观察者那里使用它。如果您稍后决定通过后台任务异步设置缩短的 URL,这还有继续工作的额外好处。
编辑
首先,有几件事。
- 让我们了解如何创建模型中的 short_url 完全。
- 我们可以吹毛求疵地说 short_url 本身根本不属于该模型,但为了保持实用性,我们将其保留在那里。
所以让我们将这个即将成为后台任务的触发器移到 Controller 中。
class ArticlesController < ApplicationController
after_filter :short_url_job, :only => [:create]
# ...
protected
def short_url_job
begin
@article.short_url = "I have a short URL"
@article.save!
rescue Exception => e
# Log thy exception here
end
end
end
显然,这个版本的 short_url_job
很愚蠢,但它说明了这一点。您可以触发 DelayedJob
、某种 resque
任务或此时的任何其他任务,您的 Controller 将从此处继续。
关于ruby-on-rails - 在 ActiveRecord 模型和观察者中访问路由的最佳方式是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7806846/