简体   繁体   中英

Calling a Rails application helper in Sidekiq worker

I have Googled this and can't seem to find an

class MyWorker

  include Sidekiq::Worker
  include ApplicationHelper

  worker code.... etc....

  myapphelper(arg)

end

I have a simple worker which at the end calls an application helper but I get:

NoMethodError: undefined method `myapphelper'

I thought adding the include ApplicationHelper would do the trick.

UPDATE

So lets add some more detail. The helper (which in fact was actually a method in my application controller) in question was originally this:

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

The idea here is I have a quick way to add a paper trail to a Model. I realized that I should perhaps not pass an actual object into the method because (like the Sidekiq docs indicate) if that object changes you could get into trouble. So I changed it to this:

  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

Now when I include this as a Module the current_user.id fails because that's set in the ApplicationController.

So lets revise my question: would the best practice to just add current_user.id as a argument to my module method or somehow keep this in the Application Controller etc.?

If I am totally off track here and this type of logic should go somewhere else please let me know.

You could accomplish the behavior by doing something like:

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

Apologize for any dumb syntax errors, but that's more or less the structure you want.

That being said, using a Module is probably overkill in this case, especially if you do not intend on re-using its method elsewhere. In that case, I'd just add a private method inside the worker.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM