【问题标题】:Calling instance method from another class ruby从另一个类 ruby​​ 调用实例方法
【发布时间】:2026-01-08 05:40:01
【问题描述】:

我遇到了这个运行时错误:

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**

如何从 cronJob 类中调用方法 loadData()?我使用控制台测试代码,如果我从控制台调用它可以正常工作: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   

【问题讨论】:

    标签: ruby ruby-on-rails-4 delayed-job


    【解决方案1】:

    不要自己创建控制器,如果你真的需要在应用程序的下部调用控制器的某些方法,请将当前控制器的实例作为变量传递。

    例子:

    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
    

    还有一件事,在 ruby​​ 中我们写 load_data 而不是 loadData :)

    还有一件事#2

    如果您的请求由假设FooController 处理,并且您想从AdminController 调用方法,这意味着您应该将load_data 方法封装在某个第三个对象(DataLoader)中。从AdminContorller 继承FooController 不是解决方案!

    【讨论】:

    • 感谢您的回答,没有更多的 loadData(),抱歉我的脑海中还有 java 世界。我已经修好了。
    • 我已经做了这个更改我得到了另一个错误:TypeError - 无法转储匿名模块:#<0x000000086f6078>