在ActiveSupport :: Concern中访问包含类的受保护常量

Ton*_* D. 6 ruby model ruby-on-rails separation-of-concerns

在ActiveSupport :: Concern上下文中访问包含类的受保护常量的最简单方法是什么?

示例类:

module Printable
    extend ActiveSupport::Concern

private
    def print_constant
        puts MY_CONSTANT
    end
end

class Printer
    include Printable

    def print
        print_constant
    end

private
    MY_CONSTANT = 'Hello'.freeze
end
Run Code Online (Sandbox Code Playgroud)

此解决方案会产生错误:

NameError: uninitialized constant Printable::MY_CONSTANT
Run Code Online (Sandbox Code Playgroud)

我知道一种似乎有效的替代方案:

puts self.class::MY_CONSTANT
Run Code Online (Sandbox Code Playgroud)

但是,感觉不对.:-)

有更好的建议吗?

Hal*_*gür 8

首先,你应该#print_constant加入一个included块:

module Printable
  extend ActiveSupport::Concern

  included do
    private

    def print_constant
      puts MY_CONSTANT
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

现在至少有两种访问类常量的方法MY_CONSTANT:

  1. #included使用base类似于Ruby的参数 产生#included:

    module Printable
      extend ActiveSupport::Concern
    
      included do |base|
        private
    
        define_method :print_constant do
          puts base::MY_CONSTANT
        end
      end
    end
    
    Run Code Online (Sandbox Code Playgroud)
  2. 另一种方法是self.class:

    module Printable
      extend ActiveSupport::Concern
    
      included do
        private
    
        def print_constant
          puts self.class::MY_CONSTANT
        end
      end
    end
    
    Run Code Online (Sandbox Code Playgroud)

ActiveSupport关注文档


ska*_*ert 1

从关注点访问包含类的常量并不是一个好主意。

关注点不应该对其所包含的类有(太多)了解。

我会在需要时寻求一个通用的 API,并在需要时重写......就像这样:

module Printable
    extend ActiveSupport::Concern

private
    def print
      puts ""
    end
end

class Printer
    include Printable

    def print
        MY_CONSTANT
    end

private
    MY_CONSTANT = 'Hello'.freeze
end
Run Code Online (Sandbox Code Playgroud)