0

我想将一堆来自子类的通用代码分解成一个超类方法。超类方法必须引用将在子类中定义的不存在的(在超类中)方法。但我无法让它工作。

这是我尝试过的多种变体中的一种:

class Superclass
    def chunk_of_code
        # <code...>
        nonexistant_superclass_method_defined_in_subclass params
        # <more code...>
    end
end

class Subclass < Superclass
    def nonexistant_superclass_method_defined_in_subclass params
        # whatever...
    end
end

Subclass.new.chunk_of_code params

这行不通。其他变体也不起作用。这种编码在 Ruby 中是否可行(我以为是)?我在 Smalltalk 工作时一直在做这种事情。

有什么方法可以实现我想要的吗?请避免建议我使用“mix-ins”或“modules”,因为我现在只想学习和使用 Ruby 的继承。

*运行最新版本的 Ruby。

谢谢。

编辑:这是在 Rails 应用程序中。超类是ApplicationController。

编辑:这是我尝试过的许多迭代之一的实际代码。这个特定的示例在视图中以“nil:NilClass 的未定义方法‘每个’”结束,显然是因为整个事情是在超级(未定义的地方)而不是子的上下文中运行的,或者至少这是我的解释:

class ApplicationController < ActionController::Base
    protect_from_forgery
    before_filter :authenticate_registration!

    # models and x defined in subclass
    def index
        models = x.where registration_id: current_registration.id

        respond_to do |format|
            format.html # index.html.erb
            format.json { render json: models }
        end
    end
    # more code here...
    # ...
end

class PositionsController < ApplicationController
    def x
        Position
    end

    def models= blah
        @positions = blah
    end

    # more code here...
    # ...
end
4

4 回答 4

3

您在这里遇到的唯一错误是chunk_of_code. 此方法必须接受一些形式参数,例如:

def chunk_of_code params

然后你可以随意调用它:

params = 'something'
Subclass.new.chunk_of_code params
于 2012-06-04T13:32:07.833 回答
1

您的错误实际上与继承无关,并且在此行

models = x.where registration_id: current_registration.id

这可能是模棱两可的:这意味着调用该方法models=还是意味着分配给一个名为 的局部变量models?在这种(和类似的)情况下,ruby 假设您正在尝试处理局部变量。如果您想调用该方法,则需要执行

self.models = x.where registration_id: current_registration.id

由于您的models=方法没有被调用,@positions因此是 nil,我假设您的视图尝试使用它。

您可能还对诸如 make_resourceful 之类的处理这种常见控制器内容的 gem 感兴趣。

于 2012-06-04T19:18:53.067 回答
0

在 Rails 的模型方面,我经常使用:

class GenericModel < ActiveRecord::Base
  self.abstract_class = true

  # define all the generic behavior methods/ model stubs you want.
  # model-specific classes can override to their hearts content
  # or use the inherited implementation

end

class Feature < GenericModel
  # model specific methods, and/or overrides
end

我用一个

class GenericController
  # basic show implementation for example
  def show
    @object = params[:controller].singularize.camelcase.constantize.find(params[:id])
    respond_to do |format|
      format.pdf { render :layout => false }
      format.html  # show
      format.xml { render :xml => @object.to_xml }
    end
  end
end

如果特定模型的显示行为与通用模型没有任何不同,则该方法不会出现在该“模型”_controller.rb 中。

于 2012-06-04T19:48:13.163 回答
-1

一种方法是在父对象中定义它并raise NotImplementedError作为方法的行为。顺便说一句,您要做的是创建一个抽象类,这在某些其他语言(如 Java)中更容易实现。

于 2012-06-04T13:27:51.647 回答