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

时间:2014-09-30 12:24:39

标签: ruby-on-rails ruby model 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

此解决方案会产生错误:

NameError: uninitialized constant Printable::MY_CONSTANT

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

puts self.class::MY_CONSTANT

但是,感觉不对。 : - )

有更好的建议吗?

2 个答案:

答案 0 :(得分:7)

首先,您应该将#print_constant放入included块:

module Printable
  extend ActiveSupport::Concern

  included do
    private

    def print_constant
      puts MY_CONSTANT
    end
  end
end

现在至少有两种方法可以访问类常量MY_CONSTANT

  1. #included产生一个类似于Ruby的base参数 #included

    module Printable
      extend ActiveSupport::Concern
    
      included do |base|
        private
    
        define_method :print_constant do
          puts base::MY_CONSTANT
        end
      end
    end
    
  2. 另一种方法来自self.class

    module Printable
      extend ActiveSupport::Concern
    
      included do
        private
    
        def print_constant
          puts self.class::MY_CONSTANT
        end
      end
    end
    
  3. ActiveSupport Concern Documentation

答案 1 :(得分: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