Ruby on 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

我想为我的rails模型添加任何类型的权限,只需在模型中包含一个模块,并在一个数据库字段中定义元数据。我怎么能做到

例如:

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