库类方法不是由rails加载的

时间:2015-07-09 16:24:59

标签: ruby-on-rails ruby

我有一个库,它定义了所有其他类派生自的基类。初始化时,Rails应提供此库中的所有类。但是,Rails不能识别从我的库类继承的类方法。这是一个例子:

型号: 应用程序/模型/ mailing_address.rb:

require 'account_model'
class MailingAddress < AccountModel
  # class accessors, initializer and method
end

图书馆班级: LIB / account_model.rb

###################################
# AccountModel
# 
# This is a super class to be inherited by 
# the domain classes of this application.
# Responsible for api calls and 
# error handling.
##
class AccountModel
  class << self
    def get_all id = nil
     # class method implementation
    end
    ##
    # get id
    # fetch method, parses url provided by child class in path hash
    # and performs appropriate fetch
    # method returns class instance set by fetch
    def get id
      # class method implementation
    end

    def update_existing options
      # class method implementation
    end

    def create_new options
      #class method implementation
    end

    def delete_existing id
      # class method implementation
    end   
end

这些方法使用HTTParty gem包装api调用。加载时,会识别方法getget_all。但是,create_newupdate_existing不是:

应用程序/控制器/ mailing_address_controller.rb:

def update
    @mailing_address = MailingAddress.update_existing params[:mailing_address]
   . . .
end

引发以下错误:

Processing by MailingAddressesController#update as JSON
. . .
Completed 500 Internal Server Error in 133ms

NoMethodError (undefined method `update_existing' for MailingAddress:Class):
  app/controllers/mailing_addresses_controller.rb:17:in `update

在Passenger中,我需要重新加载tmp / restart.txt,在WEBRick中,我需要重新启动服务器。

我在IRB中没有看到这种行为。

这是我迄今为止尝试过的,但没有成功:

  • 在config / initializers中添加初始化文件
  • 在每个模型类中添加require语句(如示例中所示)
  • 将库类包装在模块中
  • 重命名麻烦的方法(update_existing =&gt; update,foo等)

我之前从未在rails应用程序中看到过这种行为,我有另一个工作正常的库类。

我正在跑步:   - ruby​​-2.1.1   - rails 4.03   - 乘客5.07

更新:

在尝试进一步调查时,我发现了另一个问题:

我在MailingAddress中添加了一个类方法:

class MailingAddress < AccountModel
. . .
def self.debug_methods
  return self.methods
end

这也引发了一个&#34; MethodNotFound&#34;例外。由于 在rails控制台中工作,但在WEBRick或Passenger中没有,我很想过有一些服务器缓存正在进行。

更新

关闭所有内容并重新启动后,现在情况正好相反:

-WEBRick成功处理请求   - 乘客处理请求成功  -Rails控制台抛出错误:

Webrick和乘客:

Processing by MailingAddressesController#update as JSON
. . .
Completed 200 OK

控制台:

MailingAddress.update_existing params
NoMethodError: undefined method `update_existing' for MailingAddress:Class

我猜测它是先到先得的,因为任何人都可以获得加载的课程。

config.autoload_paths设置正确:

config.autoload_paths += %W(#{config.root}/lib)

最后更新 唯一可行的解​​决方法是破坏我的tmp /目录并重新启动所有内容(乘客需要touch tmp/restart.txt运行)。

然而,这是一个糟糕的解决方法。我说虫子了!

2 个答案:

答案 0 :(得分:0)

您必须在类的实例上调用该方法:

MailingAddress.new.update_existing params[:mailing_address]

@mailing_address.update_existing params[:mailing_address]

如果您不需要update_existing作为实例方法,则可以将其移出自身块。

另外,您可以考虑将account_model.rb文件放在app / models中。这样你就不必在mailing_address.rb

的顶部要求它

答案 1 :(得分:0)

服务器(Passenger,WEBRick)无法按预期可靠地加载库类。这可能是因为库类具有静态方法以及派生类。这些可能无法准确地命名空间。

当对应用程序(控制器,模型等)进行更改时会发生此行为。即使库代码可能不会更改,命名空间也会混乱。控制台每次调用时都会加载应用程序状态,其中Servers可能会缓存应用程序状态。

清除tmp目录,重新启动乘客是一种有效的解决方法。对代码的任何更改都必须被视为库更改。