Search code examples
rubyruby-on-rails-4delayed-job

Calling instance method from another class ruby


I am having this runtime error:

11843:E, [2015-05-13T11:00:00.467150 #9464] ERROR -- : 2015-05-13T11:00:00-0400: [Worker(delayed_job host:server pid:9464)] Job CronJob (id=5550d0f84d6f747bcb000000) FAILED with **NoMethodError: undefined method `loadData' for AdminController:Class**

How I can call the method loadData() from the cronJob class? I test the code using the console and it is working fine if I call from console: AdminController.new.loadData()

    class AdminController < ApplicationController

    ...

    def setLoadSchedule
        logger.debug "set hour #{params[:admin][:hour]}"
        sethour = params[:admin][:hour]

        Delayed::Job.find(Perseus::Application.config.delayed_job_id).destroy if Perseus::Application.config.delayed_job_id != :nil
    Perseus::Application.config.delayed_job_id = Delayed::Job.enqueue(CronJob.new, cron: '0 ' << sethour << ' * * 1-5')

    hide_action :loadData

    def loadData()
     ...
    end 

    private
    def isAdmin
        if !current_user.admin
        redirect_to root_path
        end
    end

    end

  class CronJob < Struct.new("CronJob")

    def perform
      AdminController.new.loadData()
    end
  end   

Solution

  • Do not create controller by yourself, if you really have to invoke some method of controller in lower part of your application, pass instance of current controller as variable.

    Example:

    def index #method of controller AdminController
      CronJob.new(self).perform #so now you are passing controller which inherits from ApplicationController, so loadData method can be invoked on it(if it is public)
    end
    

    one more thing, in ruby we write load_data not loadData :)

    one more thing#2

    if your request is handled by let's say FooController, and you want to invoke method from AdminController it means you should encapsulate load_data method in some third object (DataLoader). Inheriting in FooController from AdminContorller is not a solution!