在 child 中使用 lambda/Proc class 在 ruby 中使用

Use lambda/Proc in child class in ruby

如何使用或引用 base/super class 中定义的 lambda?

超class码

module Api
  class ApplicationSerializer
    include JSONAPI::Serializer

    # I Also tried it this way
    # serializer_for_proc = -> (object) { SerializerLookup.new.(object) }

    def serializer_for_proc
      -> (object) { SerializerLookup.new.(object) }
    end
  end
end

Childclass代码

module Api
  class AnswerSerializer < ApplicationSerializer
    attributes :values, :created_at, :updated_at, :usage

    belongs_to :question, serializer: serializer_for_proc # NameError (undefined local variable or method `serializer_for_proc' 
  end
end

如前所述,serializer_for_proc 是 Api::ApplicationSerializer 的实例方法,但您试图直接在 class 上调用它(或者更确切地说,直接在子 class).换句话说,以下所有失败的原因或多或少是相同的:

belongs_to :question, serializer: serializer_for_proc
belongs_to :question, serializer: ApplicationSerializer.serializer_for_proc
belongs_to :question, serializer: AnswerSerializer.serializer_for_proc

您实际上从未定义过 ApplicationSerializer.serializer_for_proc,您已经定义了传统上写为 ApplicationSerializer#serializer_for_proc 的内容,换句话说,ApplicationSerailizer.new.serializer_for_proc.

解决此问题的最快方法是将原始方法定义设为 class 方法:

module Api
  class ApplicationSerializer
    include JSONAPI::Serializer

    def self.serializer_for_proc
      -> (object) { SerializerLookup.new.(object) }
    end
  end
end

您在评论中写道,当您将它复制到 AnswerSerializer 文件中时,确实 起作用,但这不太可能(基本上不可能)。 的工作是将 serializer_for_proc = -> (object) { SerializerLookup.new.(object) } 版本复制到 AnswerSerializer 文件中,因为那时 serializer_for_proc 根本不是方法名称,它只是内部的一个局部变量AnswerSerializer 文件,与 x = 5 相同。但那是不可继承的。

另一种解决方案(尽管我不太喜欢)是使 serializer_for_proc 成为常数,例如:

# One file
module Api
  class ApplicationSerializer
    include JSONAPI::Serializer


    SERIALIZER_FOR_PROC = -> (object) { SerializerLookup.new.(object) }
  end
end

# Another file
module Api
  class AnswerSerializer < ApplicationSerializer
    attributes :values, :created_at, :updated_at, :usage

    belongs_to :question, serializer: SERIALIZER_FOR_PROC 
  end
end

这行得通,但我不喜欢依赖它,因为 Ruby 中基于继承的常量查找有一些 pretty weird edge cases。如果我想使用常量,我个人只会使用 Api::ApplicationSerializer::SERIALIZER_FOR_PROC