Ruby继承并需要命令

时间:2015-12-02 16:34:46

标签: ruby inheritance sinatra

我正在尝试建立一个新的模块化Sinatra应用程序。这是相关的文件夹结构:

- app 
  - controllers
    - application_controller.rb
    - website_controller.rb
  - config.ru 

application_controller.rb定义ApplicationController类,需要sinatra/base,除此之外,不做任何有趣的事情。

website_controller.rb继承application_controller.rb

# website_controller.rb
class WebsiteController < ApplicationController

  include Sinatra::Cookies
  ...
end

我的config.ru文件是我为启动Sinatra应用而运行的,所以应该要求所有类:

#config.ru
require 'sinatra/base'

Dir.glob('./app/{models,helpers,controllers}/*.rb').each {|file|
  require file
}

...

如果需要所有文件,则在需要website_controller.rb之前需要application_controller.rb。这样,当解析WebsiteController上的继承时,它还不知道ApplicationController是什么,我得到错误uninitialized constant ApplicationController (NameError)

设置项目的最佳做法是什么,以便在不遇到这种排序问题的情况下准备好所有必需的文件?

2 个答案:

答案 0 :(得分:3)

所以,另一个答案实际上是正确和最简单的方法 - 但如果由于某种原因您不想这样做,您可以使用autoload,前提是您已经开发了Sinatra应用程序“模块化”风格。

config.ru中,您目前正在“急切地”加载所有文件。相反,您将明确列出未知常量的加载路径 - 如下所示:

autoload :ApplicationController, 'app/controllers/application_controller'
autoload :WebsiteController, 'app/controllers/website_controller'

请注意,autoloadModule上的一种方法,因此您必须将autoload的调用放在同一个“命名空间”中 - 即:

module MyApp
  autoload :MyThing, 'models/my_thing'
end

当缺少常量MyApp::MyThing时将触发自动加载。这就是说 - 除非你知道为什么你需要自动加载你的类,只需要在文件顶部需要它。

答案 1 :(得分:2)

website_controller.rb的顶部,需要application_controller.rb

你可能觉得它多余,但这不会造成伤害。这是最强大的方式。