在我的 ruby on Rails 应用程序中,当我更改代码时(例如将第 5 行从 更改为 ),i = f1
我i = f2
收到此错误:
Api::V1::AppController#login 中的 NoMethodError
#Master::Utilities:0x00007fdb6ceb42c8 的未定义方法“f2”
这是我的代码
class Api::V1::AppController < ApplicationController
def login
c = Master::Utilities.new
i = c.f1
z = c.f2
render json: {m: 'login' , msg: "hello" , data: "#{z} - #{i}" } , status: :ok
end
end
撤消更改并不能解决问题。收到此错误后,我重新启动Puma,一切都恢复正常,无需更改代码。
这些是我的代码
lib\master\utilities.rb
module Master class Utilities Dir[File.join(__dir__, 'code', '*.rb')].each { |file| require file } end end
lib\master\code\1.rb
module Master class Utilities def f1 "Function 1" end end end
lib\master\code\2.rb
module Master class Utilities def f2 "Function 2" end end end
我使用此代码来config\application.rb
自动加载我的代码
config.paths.add Rails.root.join('lib').to_s, eager_load: true
我是 ruby on Rails 的新手,我认为我的代码中有一个小错误,但我找不到哪里。
谢谢
这里的问题是,当您编辑文件时,rails 会看到
Master::Utilities.new
对Master::Utilities
. 但当谈到这一部分时:...例如,它看到
lib/master/code/1.rb
已经加载了。(require
不会重新加载已加载的文件!)。因此,没有定义任何方法定义,因此实际上您最终会得到一个
Master::Utilities
没有实例方法的类。一个快速、最小的修复方法是将上面的内容替换
require
为load
,明确表示“始终加载文件,即使它之前已加载”:然而,我要指出的是,这是在 ruby/rails 中构建代码的一种非常不寻常的方式;如果采用更传统的方法,您可能会受益更多。
将单个类的定义拆分为多个文件有什么好处/逻辑?如果您想查找方法的定义位置,将它们全部放在一个位置,或者将它们拆分为逻辑模块不是更容易吗?
如果遵循“仅在一处定义类,并使类名与文件名匹配”的约定,那么 Rails 中的预加载将开箱即用地顺利工作。例如,您也许可以这样做:
或者:
或者,如果您确实希望将所有方法放在一个巨大的类中,并自动加载文件夹中的所有文件(即使这对我来说听起来非常混乱!),您可以编写一些元编程 - 例如使用将文件名转换
String#classify
为他们的模块名称。