【问题标题】:Calling a Rails application helper in Sidekiq worker在 Sidekiq worker 中调用 Rails 应用程序助手
【发布时间】:2016-02-29 22:12:53
【问题描述】:

我用谷歌搜索了这个,但似乎找不到

class MyWorker

  include Sidekiq::Worker
  include ApplicationHelper

  worker code.... etc....

  myapphelper(arg)

end

我有一个简单的工作人员,它最后调用了一个应用程序助手,但我得到了:

NoMethodError: undefined method `myapphelper'

我认为添加 include ApplicationHelper 可以解决问题。

更新

所以让我们添加更多细节。有问题的助手(实际上是我的应用程序控制器中的一个方法)最初是这样的:

def add_history(resource, action, note)

    resource.history.create(action: action, note: note, user_id: current_user.id) if resource.present? && action.present? && note.present?

end

这里的想法是我有一种快速的方法来向模型添加书面记录。我意识到我可能不应该将实际对象传递给该方法,因为(如 Sidekiq 文档所示)如果该对象发生更改,您可能会遇到麻烦。所以我把它改成了这样:

  def add_history(klass, id , action, note)

    resource = klass.constantize.find_by(id: id)
    resource.history.create(action: action, note: note, user_id: current_user.id) if resource.present? && action.present? && note.present?

  end

现在,当我将它作为模块包含在内时,current_user.id 会失败,因为它是在 ApplicationController 中设置的。

所以让我们修改一下我的问题:最好的做法是将 current_user.id 作为参数添加到我的模块方法中,还是以某种方式将其保留在应用程序控制器等中?

如果我在这里完全偏离了轨道并且这种类型的逻辑应该转到其他地方,请告诉我。

【问题讨论】:

  • ApplicationHelpers 不打算在视图之外的任何东西中使用。考虑将您的方法移动到一个普通的旧模块,并包含它。
  • 嗯......你是对的......我想我完全以错误的方式接近那个助手。如果您将此添加为答案,我会接受它,因为据我所知,即使您指出了对我来说显而易见的事情,它也是正确的 :)
  • 包含不起作用,因为此模块超出了工作人员的视野范围。您还需要像 require '/filepath' 这样的文件
  • 很高兴,谢谢!祝你好运!
  • 只需添加传递 current_user id 的参数

标签: ruby-on-rails sidekiq


【解决方案1】:

您可以通过执行以下操作来完成该行为:

class HistoryWorker
   include Sidekiq::Worker
   include History # or whatever you want to call it

  def perform(klass, id , action, note, user_id)
    add_history(klass, id, action, note, user_id)
  end

end

module History
  def add_history(klass, id, action, note, user_id)
    resource = klass.constantize.find_by(id: id)
    resource.history.create(action: action, note: note, user_id: user_id) if resource.present? && action.present? && note.present?
  end
end

class ApplicationController < ActionController::Base
  after_filter :save_history

  def save_history
     HistoryWorker.perform_async(class: resource.class.name, id: resource.id, action: params[:action], note: 'some note', user_id: current_user.id)
  end
end

为任何愚蠢的语法错误道歉,但这或多或少是你想要的结构。

话虽如此,在这种情况下使用模块可能有点过头了,特别是如果您不打算在其他地方重复使用它的方法。在这种情况下,我只需在工作人员中添加一个私有方法。

【讨论】:

  • 这就是我所做的。我将它保留为一个直接模块,因为随着各种行的创建、更新等,我将在我的应用程序中调用它。我会指出,将你的模块命名为与你的模型名称相同是有问题的。我做了你所拥有的,在重新启动我的应用程序后,我遇到了各种各样的错误。我没有深入研究它,因为它更容易重命名HistoryModule vs History
  • 哦,有趣。您可能正在使用已声明 History 命名空间的 gem 或某些第三方代码,因为我认为 Rails 没有在任何地方声明。不管怎样,很高兴你把它整理好了。
猜你喜欢
  • 2015-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-04
  • 2014-09-07
相关资源
最近更新 更多