在ActiveRecord模型和观察者中访问路径的最佳方法是什么

时间:2011-10-18 11:58:36

标签: ruby-on-rails ruby-on-rails-3

我有一种情况,我想在数据库中创建一条记录(更新表中存储短网址的列)后向第三方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

但这对我来说似乎不是一个干净的解决方案,是否有人指出这个问题或者有关应如何做的任何建议?

提前致谢。

1 个答案:

答案 0 :(得分:0)

我绝对不会让你的模特知道你的路线。相反,在attr_accessor :unshortened_url课程中添加Article之类的内容。在控制器中设置该字段,然后从观察者中使用它。如果您以后决定通过后台任务异步设置缩短的URL,这还有继续工作的额外好处。

修改

首先是一些事情。

  1. 让我们从模型中获取创建 short_url的知识 完全。
  2. 我们可以挑剔地说,short_url本身并不属于模型,但为了保持实用,让它留在那里。
  3. 因此,让我们将这个即将成为背景的任务的触发器移动到控制器中。

    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任务,或此时的任何操作,您的控制器将从此处继续执行。