我正在对API进行更改,因此新版本在Api::V2
模块下被命名空间。旧API位于API
命名空间下。我希望能够从旧控制器继承和覆盖一些东西。
如果我这样做,它可以正常工作:
module Api
module V2
class ResourcesController < ::Api::ResourcesController
include Crud
父类::Api::ResourcesController
定义model
方法,此方法在options
方法中使用,::Api::Crud
模块也需要。
# app/controllers/resources_controller.rb
protected
def model
Resource
end
# app/controllers/concerns/api/crud.rb
def model
raise "Model must be defined"
end
但是,我需要进行的更改是在Crud
模块中,因此我创建了该模块的命名空间版本。
# app/controllers/concerns/api/v2/crud.rb
module Api
module V2
module Crud
include ::Api::Crud
include ::Api::V2::ReadOnly
因此,这个新模块仍在使用model
方法,如果未定义错误,则会引发错误,方法是将其包含在::Api::Crud
中。现在,当我尝试在我的控制器中使用这个新模块时:
# app/controllers/api/vw/resources_controller.rb
module Api
module V2
class ResourcesController < ::Api::ResourcesController
include ::Api::Crud
我收到错误Model must be defined
。为什么它找不到我的父控制器类中定义的model
方法?
答案 0 :(得分:3)
如果你这样做
class Base
end
module Special
end
class Derived < Base
include Special
end
然后Derived.ancestors
为[Derived, Special, Base, Object, Kernel, BasicObject]
即。在寻找方法时,ruby首先查看Derived
,然后查看模块Special
,然后查看Base
。
并不是ruby在父控制器类中找不到model
方法,而是搜索顺序首先从模块中找到版本。