从ruby中的模块中调用类方法

时间:2014-01-29 22:58:26

标签: ruby-on-rails ruby activerecord

场景:我的rails系统中有几个ActiveRecord模型,都需要通过访问控制列表进行控制。我有一个很好的小ACL实现,可以实现我想要的,但是现在check-access调用都在每个受控对象类型(文档,用户等)中都是重复的。

我的直觉是将共享代码拉入模块并将其与mixin一起使用。我不确定这是可能的(或者正确的语法是什么),因为混合模块调用了ActiveRecord :: Base方法 - 有范围和has_many定义。

我想要完成的例子是:

class Document < ActiveRecord::Base
  include Controlled
end

module Controlled 
  has_many :acls, as: :controlled
  scope :accessible, ->(uid, level){where("BUNCH OF SQL HERE")}
  def access_convenience_methods
    #stuff to provide easy access to authorization checks
  end
end

然后我会从ActiveRecord :: Base派生出一些包含Controlled的其他模型。

模块中的has_many和scope调用引起了心痛 - 我无法在混合模块中调用它们,显然这个上下文无法访问外部类方法。

欢迎任何建议。

2 个答案:

答案 0 :(得分:2)

你是对的,因为你不能像这样从模块中调用类方法。

现在,执行此操作所需的样板代码已包含在ActiveSupport::Concern中;它完全符合你的要求。

[编辑]:我还建议你学习the boilerplate code itself,因为它非常简短易读,是Ruby元编程的一个很好的例子。

答案 1 :(得分:0)

啊哈,这显然是一个红宝石新手的失败 - 我需要将has_many和其他一次性调用放在一个包含的块中。似乎ActiveSupport :: Concern在这里使用是正确的:

module Controlled 
  extend ActiveSupport::Concern
  included do
    has_many :acls, as: :controlled
    scope :accessible, ->(uid, level){where("BUNCH OF SQL HERE")}
  end
  def access_convenience_methods
    #stuff to provide easy access to authorization checks
  end
end