我担心存储常量:
module Group::Constants
extend ActiveSupport::Concern
MEMBERSHIP_STATUSES = %w(accepted invited requested
rejected_by_group rejected_group)
end
另一个关注我希望使用这些常量:
module User::Groupable
extend ActiveSupport::Concern
include Group::Constants
MEMBERSHIP_STATUSES.each do |status_name|
define_method "#{status_name}_groups" do
groups.where(:user_memberships => {:status => status_name})
end
end
end
不幸的是,这会导致路由错误:
uninitialized constant User::Groupable::MEMBERSHIP_STATUSES
看起来第一个问题是在第二个问题中没有正确加载。如果是这样的话,我该怎么办呢?
答案 0 :(得分:29)
看来这种行为是设计的,正如here所解释的那样。
在这种情况下,您需要做的是Group::Constants
从ActiveSupport::Concern
延伸,因为这会阻止其实现与其他ActiveSupport::Concern
扩展模块共享(尽管它会最终在包含第二个模块的类中共享:
module A
TEST_A = 'foo'
end
module B
extend ActiveSupport::Concern
TEST_B = 'bar'
end
module C
extend ActiveSupport::Concern
include A
include B
end
C::TEST_A
=> 'foo'
C::TEST_B
=> uninitialized constant C::TEST_B
class D
include C
end
D::TEST_A
=> 'foo'
D::TEST_B
=> 'bar'
简而言之,您需要将Group::Constants
作为标准模块,然后一切都会好起来。
答案 1 :(得分:0)
如果要将所有内容保存在一个文件中,并且可以忍受一些样板,则可以将模块分为“关注”位和“无关”位:
module A
FOO = [22]
def self.included base
base.include Concern
end
module Concern
extend ActiveSupport::Concern
class_methods do
def foo_from_the_perspective_of_a_class_method_in_A
{lexical: FOO, instance: self::FOO}
end
end
end
end
module B
extend ActiveSupport::Concern
include A
FOO += [33]
def foo_from_the_perspective_of_an_instance_method_in_B
FOO
end
end
class C
include B
end
C.foo_from_the_perspective_of_a_class_method_in_A
=> {:lexical=>[22], :instance=>[22, 33]}
C.new.foo_from_the_perspective_of_an_instance_method_in_B
=> [22, 33]
C::FOO
=> [22, 33]