Ruby on rails rails模型单个字段中的简单权限
我想为我的rails模型添加任何类型的权限,只需在模型中包含一个模块,并在一个数据库字段中定义元数据。我怎么能做到 例如:Ruby on rails rails模型单个字段中的简单权限,ruby-on-rails,ruby,Ruby On Rails,Ruby,我想为我的rails模型添加任何类型的权限,只需在模型中包含一个模块,并在一个数据库字段中定义元数据。我怎么能做到 例如: Folder < AR::B @permissions_list = [:is_private, :public_on_negotioation] @permissions_field = :perms include Permissions end module Permissions "...?" end 所以我写了下一个模块: module
Folder < AR::B
@permissions_list = [:is_private, :public_on_negotioation]
@permissions_field = :perms
include Permissions
end
module Permissions
"...?"
end
所以我写了下一个模块:
module Permissions
def self.included(mod)
permissions_list = mod.instance_variable_get(:@permissions_list)
permissions_list.each_with_index do |permission, index|
define_method permission.to_sym do
perms_bits[index] == '1'
end
alias_method (permission.to_s << "?").to_sym, permission.to_sym
end
end
def perms_bits
send(self.class.instance_variable_get(:@permissions_field)).to_i.to_s(2).reverse
end
def set_permission(name, weight, options)
permissions_field = self.class.instance_variable_get(:@permissions_field)
if options[name]
self.send("#{permissions_field}=", self.send(permissions_field).to_i + weight.to_i) unless send(name)
elsif options.has_key?("#{name}_off")
self.send("#{permissions_field}=", self.send(permissions_field).to_i - weight.to_i) if send(name)
end
end
def update_perms(options)
permissions_list = self.class.instance_variable_get(:@permissions_list)
permissions_list.each_with_index do |permission, index|
set_permission(permission.to_sym, 2**index, options)
end
save
end
end
模块权限
def包括在内(mod)
permissions\u list=mod.instance\u variable\u get(:@permissions\u list)
权限列表。每个带有索引的权限都有权限,索引|
定义方法权限
perms_位[索引]=“1”
结束
alias_方法(permission.to_s查看:
文件夹正确
如果需要动态定义访问器方法:
Folder < AR::B
[:is_private, :public_on_negotiation].each do |action|
define_method("#{action}?") do
permissions.send action
end
end
# And so on for "#{action}=", ...
end
文件夹请记住:重构取决于您!:-)扩展mdesantis的答案。将权限代码打包以供重用的方法可以是这样的(未经测试):
class文件夹
我只想包括一个模块来建模和获取所有功能,但不要为每个权限编写几十个代码,因为可能有很多。但无论如何,谢谢。我的回答是对你所要求的概念的证明;方法问题是另一个问题,可以使用元编程来解决。检查f.e。
Folder < AR::B
# Must be costant, otherwise Rails will raise an
# ActiveRecord::SerializationTypeMismatch
PERMISSIONS_STRUCT = Struct.new(:is_private, :public_on_negotiation)
serialize :permissions, PERMISSIONS_STRUCT
def is_private?
permissions.is_private
end
def is_private=(is_private)
permissions.is_private = is_private
end
# The same for public_on_negotiation
end
f = Folder.new
f.is_private = true
f.save
f.reload
f.is_private?
=> true
Folder < AR::B
[:is_private, :public_on_negotiation].each do |action|
define_method("#{action}?") do
permissions.send action
end
end
# And so on for "#{action}=", ...
end
class Folder < ActiveRecord::Base
include Permissions
end
PERMISSIONS_STRUCT = Struct.new(:is_private, :public_on_negotiation)
module Permissions
def self.included(klass)
klass.class_eval do
serialize :permissions, PERMISSIONS_STRUCT
end
klass.include(InstanceMethods)
end
module InstanceMethods
def is_private?
permissions.is_private
end
def is_private=(is_private)
permissions.is_private = is_private
end
end
end