受保护的方法不是Inherited

时间:2016-05-11 20:29:23

标签: ruby-on-rails ruby inheritance

我正在对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方法?

1 个答案:

答案 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方法,而是搜索顺序首先从模块中找到版本。