为这3种方法写一个通用的方法

时间:2011-05-27 19:33:25

标签: ruby-on-rails ruby

我有一个像这样的模型用户

class User

  ROLES = {
            "Admin" => 1,
            "Manager" => 2,
            "Officer" => 3
          }

  def admin?
    role == 1
  end

  def manager?
    role == 2
  end

  def officer?
    role == 3
  end

end

其中roleusers表中的一列,我想知道是否可以使用常用方法从ROLES哈希构建3个角色检查方法?

修改

所以这似乎就是答案

class User

  ROLES = {
            "Admin" => 1,
            "Manager" => 2,
            "Officer" => 3
          }

  # methods used to identify whether a user is a specific role
  ROLES.each { |k, v| define_method("#{k.downcase}?") { role == v } }

end

4 个答案:

答案 0 :(得分:2)

我认为有几种选择。

首先,您可以添加method_missing实现来检查该方法是否是您的角色名称之一。类似的东西:

def method_missing?(sym, *args)
  if args.empty? && ROLES.any? { |r| r.downcase + "?" == sym.to_s }
    # No additional arguments and the symbol for the method called 
    # matches a role name
    role == ROLES[sym.to_s.chomp('?')] # Check the value
  else
    super
  end
end

或者,您可以从角色哈希设置方法:

class User
  ROLES = { ... }
  ROLES.each_pair do |r, n|
    class_eval "def #{r.downcase}?; role == #{n}; end"
  end
end

答案 1 :(得分:2)

我不完全确定你的意图,但也许是这样的?

class User
  %w[admin manager officer].each_with_index{|m, i| define_method("#{m}?"){role == i+1}}
end

或使用ROLES

class User
  ROLES.each{|m, i| define_method("#{m.downcase}?"){role == i}}
end

答案 2 :(得分:1)

可能有几种不同的方法,问题是,您希望它如何表现,以及您希望在何处使用易用性/灵活性?

如果我掌握了你想要做的事情,这样的事情可能会有所帮助

def to_methods(roles_hash)
  roles_hash.each_pair do |key, value|
    class_eval {
      "def #{key}?
         role == #{value}
       end" 
    }
  end
end

这将为您创建每个角色的方法。那是你想要做的吗?

答案 3 :(得分:1)

我想你可以做这样的事情,但我认为你的方式更好......

  (ROLES = {
    "Admin"   => 1,
    "Manager" => 2,
    "Officer" => 3,
  }).each { |k, v| define_method(k.downcase + '?') { role == v }}