问题
您的问题源于这样一个事实,即 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的一部分,所以这段代码可能会在版本之间中断宝石。