基本上我想实现一个简单的Rails扩展来定义控制器中方法的严重性,以便我可以适当地限制它们的使用。例如,我在一个抽象的超类中定义了默认的restful动作:
view_methods :index, :show
edit_methods :new, :create, :edit, :update
destroy_methods :destroy
然后我将进入一个非抽象的控制器调用:
edit_methods :sort
将该特定控制器上的sort方法添加为编辑级别方法。
然后我可以使用before_filter来检查当前正在执行的操作的级别,如果我的逻辑确定当前用户无法执行,则中止它。
麻烦的是,我在弄清楚如何设置这种结构时遇到了麻烦。到目前为止,我尝试过这样的事情:
class ApplicationController
@@view_methods = Array.new
@@edit_methods = Array.new
@@destroy_methods = Array.new
def self.view_methods(*view_methods)
class_variable_set(:@@view_methods, class_variable_get(:@@view_methods) << view_methods.to_a)
end
def self.edit_methods(*edit_methods)
class_variable_set(:@@edit_methods, self.class_variable_get(:@@edit_methods) << edit_methods.to_a)
end
def self.destroy_methods(*destroy_methods)
@@destroy_methods << destroy_methods.to_a
end
def self.testing
return @@edit_methods
end
view_methods :index, :show
edit_methods :new, :create, :edit, :update
destroy_methods :destroy
end
上述三种方法的目的不同,只是为了向您展示我的尝试。第三个工作,但无论我测试什么控制器,返回相同的结果。可能是因为类变量存储在应用程序控制器中,因此全局更改。
非常感谢任何帮助。
答案 0 :(得分:3)
问题是您的类变量是继承的,但指向Array
的同一个实例。如果您更新一个,它也将在继承Array
。
ActiveSupport
通过使用多种方法扩展Class
类来定义可继承的类属性,为此问题提供solution。它们在Rails内部随处使用。一个例子:
class ApplicationController
class_inheritable_array :view_method_list
self.view_method_list = []
def self.view_methods(*view_methods)
self.view_method_list = view_methods # view_methods are added
end
view_methods :index, :show
end
现在,您可以在ApplicationController
中设置默认值并稍后覆盖它们。
class MyController < ApplicationController
view_method :my_method
end
ApplicationController.view_method_list #=> [:index, :show]
MyController.view_method_list #=> [:index, :show, :my_method]
您甚至可以在控制器上使用view_method_list
作为实例方法(例如MyController.new.view_method_list
)。
在您的示例中,您没有定义从列表中删除方法的方法,但其目的是执行以下操作(如果您需要):
# given the code above...
class MyController
self.view_method_list.delete :show
end
MyController.view_method_list #=> [:index, :my_method]
答案 1 :(得分:0)
我把它变成了这样一个插件:
module ThreatLevel
def self.included(base)
base.send :extend, ClassMethods
end
module ClassMethods
def roger_that!
class_inheritable_array :view_method_list, :edit_method_list, :destroy_method_list
self.view_method_list = Array.new
self.edit_method_list = Array.new
self.destroy_method_list = Array.new
def self.view_methods(*view_methods)
self.view_method_list = view_methods
end
def self.edit_methods(*edit_methods)
self.edit_method_list = edit_methods
end
def self.destroy_methods(*destroy_methods)
self.destroy_method_list = destroy_methods
end
view_methods :index, :show
edit_methods :new, :create, :edit, :update
destroy_methods :destroy
end
end
end
ActionController::Base.send :include, ThreatLevel
打电话给roger_that!在你想让它生效的super_controller上就可以了。xt