Rails 4 - Resque 背景作业中的印象派
Rails 4 - Impressionist Inside of a Resque Background Job
我正在使用 Rails 4 w/ 印象派和 resque gem。
我正在使用印象派在我的文章显示页面上记录唯一会话点击。由于性能问题并且不需要向用户显示命中(仅供管理员使用),我想将日志记录移到后台。
通常我会使用 impressionist(@article, unique: [:session_hash])
记录印象,但要通过 resque 将其移到背景中,我现在正在做这样的事情...
articles_controller:
def show
.
.
.
Resque.enqueue(ImpressionLogger, @article.id)
end
app/workers/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 中包含印象派方法。
印象派是否正确安装了捆绑器?如果是这样,Rails 应该将其加载到您的环境中。我会检查您是否可以在 Rails 代码的其他地方访问 impressionist
功能(即不通过 Resque)作为调试它的第一步。
你是如何启动你的 resque worker 的?如果您需要加载 Rails 环境,请尝试 rake environment resque:work
.
https://github.com/resque/resque/wiki/FAQ#how-do-i-ensure-my-rails-classesenvironment-is-loaded
问题
你的问题源于这样一个事实,即印象派在控制器级别工作,因为在任何 ActionController 实例的引擎初始化程序中包含一个带有 impressionist
方法的模块:
https://github.com/charlotte-ruby/impressionist/blob/master/lib/impressionist/engine.rb#L11
您正在尝试从 Resque 作业中调用的常规 class 调用印象派方法,因此不会定义该方法。
解决方案
这有点恶心,但如果你真的想使用印象派,我们可以深入研究这个......看看发现的印象派方法的实际实现 here,我们看到以下内容:
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 包装器似乎只有在您想要实现 this functionality. Which it looks like you do. The call to associative_create_statement
seems to be pulling parameters based off of the controller name as well as parameters passed from Rack such as the useragent string and ip address (here) 时才重要。因此,您必须在调用 Resque 作业之前解析这些值。
此时我的建议是实施一个 Resque class,它接受两个参数,一个 article_id 和您想要的印象参数。 resque class 将直接在易受影响的对象上创建印象。您的请求 class 将变为:
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 的 public API,因此此代码可能会在 gem.
的版本之间中断
我正在使用 Rails 4 w/ 印象派和 resque gem。
我正在使用印象派在我的文章显示页面上记录唯一会话点击。由于性能问题并且不需要向用户显示命中(仅供管理员使用),我想将日志记录移到后台。
通常我会使用 impressionist(@article, unique: [:session_hash])
记录印象,但要通过 resque 将其移到背景中,我现在正在做这样的事情...
articles_controller:
def show
.
.
.
Resque.enqueue(ImpressionLogger, @article.id)
end
app/workers/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 中包含印象派方法。
印象派是否正确安装了捆绑器?如果是这样,Rails 应该将其加载到您的环境中。我会检查您是否可以在 Rails 代码的其他地方访问 impressionist
功能(即不通过 Resque)作为调试它的第一步。
你是如何启动你的 resque worker 的?如果您需要加载 Rails 环境,请尝试 rake environment resque:work
.
https://github.com/resque/resque/wiki/FAQ#how-do-i-ensure-my-rails-classesenvironment-is-loaded
问题
你的问题源于这样一个事实,即印象派在控制器级别工作,因为在任何 ActionController 实例的引擎初始化程序中包含一个带有 impressionist
方法的模块:
https://github.com/charlotte-ruby/impressionist/blob/master/lib/impressionist/engine.rb#L11
您正在尝试从 Resque 作业中调用的常规 class 调用印象派方法,因此不会定义该方法。
解决方案
这有点恶心,但如果你真的想使用印象派,我们可以深入研究这个......看看发现的印象派方法的实际实现 here,我们看到以下内容:
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 包装器似乎只有在您想要实现 this functionality. Which it looks like you do. The call to associative_create_statement
seems to be pulling parameters based off of the controller name as well as parameters passed from Rack such as the useragent string and ip address (here) 时才重要。因此,您必须在调用 Resque 作业之前解析这些值。
此时我的建议是实施一个 Resque class,它接受两个参数,一个 article_id 和您想要的印象参数。 resque class 将直接在易受影响的对象上创建印象。您的请求 class 将变为:
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 的 public API,因此此代码可能会在 gem.