我有一种情况,我想在数据库中创建一条记录(更新表中存储短网址的列)后向第三方API(网址缩短服务)发出请求,以便解耦来自Model的API请求,我已经设置了一个ActiveRecord Observer,它在每次创建记录时都会使用after_create
回调钩子,这里是相关的代码:
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路由在Model或ModelObservers中都不可用,与ActionMailer相同(Mails中存在类似问题,如果我们需要放置一个URL,我们必须配置“ActionMailer” :: default_options_url“)。理论上,在Model中访问路径/请求对象被认为是一种糟糕的设计。为了避免上述问题,我可以包含url_helpers
模块,如以下URL中所述:
http://slaive-prog.tumblr.com/post/7618787555/using-routes-in-your-model-in-rails-3-0-x
但这对我来说似乎不是一个干净的解决方案,是否有人指出这个问题或者有关应如何做的任何建议?
提前致谢。
答案 0 :(得分:0)
我绝对不会让你的模特知道你的路线。相反,在attr_accessor :unshortened_url
课程中添加Article
之类的内容。在控制器中设置该字段,然后从观察者中使用它。如果您以后决定通过后台任务异步设置缩短的URL,这还有继续工作的额外好处。
修改强>
首先是一些事情。
因此,让我们将这个即将成为背景的任务的触发器移动到控制器中。
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
任务,或此时的任何操作,您的控制器将从此处继续执行。