4

我正在使用带有印象派和 resque gem 的 Rails 4。

我正在使用印象派在我的文章显示页面上记录独特的会话点击。由于性能问题并且不需要向用户显示命中(仅适用于管理员),我想将记录印象移到后台。

通常我会使用但要通过 resque 将其移入 bg 来记录印象impressionist(@article, unique: [:session_hash]),我现在正在做这样的事情......

文章控制器:

def show
  .
  .
  .
  Resque.enqueue(ImpressionLogger, @article.id)
end

应用程序/工人/impression_logger.rb:

class ImpressionLogger 

  @queue = :impression_queue

  def self.perform(article_id)
    article = Article.find(article_id)
    impressionist(article, unique: [:session_hash])
  end

end

当我这样设置时,当 resque 尝试处理作业时,它正在返回undefined method "impressionist" for ImpressionLogger:Class. 你们认为最好的解决方法是什么?我不确定如何在我的 resque worker 中包含印象派方法。

4

3 回答 3

2

问题

您的问题源于这样一个事实,即 Impressionist 在控制器级别上工作,因为impressionist在 ActionController 的任何实例的引擎初始化程序中包含一个带有该方法的模块:

https://github.com/charlotte-ruby/impressionist/blob/master/lib/impressionist/engine.rb#L11

您正在尝试从 Resque 作业中调用的常规类调用印象派方法,因此不会定义该方法。

解决方案

这有点恶心,但是如果你真的想使用印象派,我们可以深入研究一下……查看此处找到的印象派方法的实际实现,我们看到以下内容:

def impressionist(obj,message=nil,opts={})
  if should_count_impression?(opts)
    if obj.respond_to?("impressionable?")
      if unique_instance?(obj, opts[:unique])
        obj.impressions.create(associative_create_statement({:message => message}))
      end
    else
      # we could create an impression anyway. for classes, too. why not?
      raise "#{obj.class.to_s} is not impressionable!"
    end
  end
end

假设你要手动调用这样的东西(就像你想从一个 resque 工作中那样),关键是这三行:

if unique_instance?(obj, opts[:unique])
  obj.impressions.create(associative_create_statement({:message => message}))
end

如果你想实现这个功能,if 包装器似乎很重要。它看起来像你做的。调用associative_create_statement似乎是根据控制器名称以及从 Rack 传递的参数(例如用户代理字符串和 ip 地址(此处))提取参数。因此,您必须在调用 Resque 作业之前解析这些值。

我现在建议的是实现一个 Resque 类,它接受两个参数,一个 article_id 和你想要的印象参数。然后 resque 类将直接在可印象对象上创建印象。您的 Resque 课程将变为:

class ImpressionLogger 
  @queue = :impression_queue

  def self.perform(article_id, impression_params = {})
    article = Article.find(article_id)
    article.impressions.create(impression_params)
  end
end

你的控制器方法看起来像这样:

def show
  .
  .
  .
  Resque.enqueue(ImpressionLogger, @article.id, associative_create_statement({message: nil})) if unique_instance?(@article, [:session_hash])
end

免责声明

虽然这样做有一个相当大的免责声明......该方法associative_create_statement被标记为受保护并被unique_instance?标记为私有......所以这些都不是印象派gem的公共API的一部分,所以这段代码可能会在版本之间中断宝石。

于 2016-04-29T19:28:58.263 回答
1

印象派是否使用捆绑器正确安装?如果是这样,Rails 应该将其加载到您的环境中。我会检查您是否可以impressionist在 Rails 代码的其他地方访问功能(即不通过 Resque)作为调试的第一步。

于 2016-04-12T19:17:56.460 回答
0

你是如何开始你的 resque 工人的?如果您需要加载 Rails 环境,请尝试rake environment resque:work.

https://github.com/resque/resque/wiki/FAQ#how-do-i-ensure-my-rails-classesenvironment-is-loaded

于 2016-04-12T21:20:44.483 回答