1

鉴于以下情况:

class User; attr_accessor :roles; end

module RegisteredUser
  def default_context
    Submission
  end
end

module Admin
  def default_context
    Review
  end
end

current_user = User.new
current_user.roles = ["registered_user", "admin"]
current_user.roles.each do |role|
  role_module = role.gsub(/ /, '_').camelize
  if module_exists?(role_module)
    current_user.extend role_module.constantize
  end
end
context = self.extend current_user.default_context

有没有办法设置优先级User#default_context?也就是说,我可以说无论扩展的顺序如何,Admin#default_context总是优先吗?RegisteredUser#default_contextcurrent_user

4

3 回答 3

2

method_addedModule.

我实际上的意思是included,不是extended,但两者都在Module

该机制将围绕执行以下操作:

module Foo
  def self.included(base)
    base.extend(FooMethods)
  end

  module FooMethods
    def bar
      # Whatever
    end
  end
end

在内部Foo.included,您可以根据任意标准确定是否应将相关方法添加到base(包括模块的实体)。

在您的情况下,您可以检查是否已经包含“更高优先级”模块,或者查看该模块是否是“更高优先级”模块。基于此,您将决定是否添加方法。

于 2011-11-30T16:38:50.873 回答
1

由于管理员也是注册用户,我会这样做

module Admin
  include RegisteredUser
  ...
end

然后只有

current_user.extend Admin

我不确定这是否是正确的方法。如果 Admin 和 RegisteredUser 是类,那么让 Admin 继承自 RegisteredUser 是有意义的。如果是模块,不知道。

于 2011-11-30T16:31:31.160 回答
1

你不能; 在 Ruby 中,模块包含的顺序是搜索模块的顺序(在当前类之后,在父类之前)。更改“优先级”的唯一方法是以您想要的顺序包含模块,或者将它们移动到父类。

虽然不是纯 Ruby,但您可以使用banisterfiend的Remix库来更改模块顺序(或取消混合模块,或...其他事情)。

于 2011-11-30T16:35:24.153 回答