我有一个库,它定义了所有其他类派生自的基类。初始化时,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调用。加载时,会识别方法get
和get_all
。但是,create_new
和update_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中没有看到这种行为。
这是我迄今为止尝试过的,但没有成功:
我之前从未在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
运行)。
答案 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目录,重新启动乘客是一种有效的解决方法。对代码的任何更改都必须被视为库更改。