Ruby on rails 在Rails中创建一个处理多个方法名的方法?

Ruby on rails 在Rails中创建一个处理多个方法名的方法?,ruby-on-rails,ruby,ruby-on-rails-4,Ruby On Rails,Ruby,Ruby On Rails 4,是否可以干燥以下代码: def is_user? is_role? ROLES[:user] end def is_mod? is_role? ROLES[:mod] end def is_admin? is_role? ROLES[:admin] end private def is_role?(role) self.roles & role == role end 集成到单个函数中,但仍然能够像当前一样调用函数名(是用户?,是模块?,等等) 更新: 使用以下

是否可以干燥以下代码:

def is_user?
  is_role? ROLES[:user]
end

def is_mod?
  is_role? ROLES[:mod]
end

def is_admin?
  is_role? ROLES[:admin]
end

private

def is_role?(role)
  self.roles & role == role
end
集成到单个函数中,但仍然能够像当前一样调用函数名(
是用户?
是模块?
,等等)

更新:

使用以下Aetherus的答案,我创建了以下用于管理用户角色的内容(其中用户可以有多个角色):

class用户
您可以用一个ruby代码块定义多个方法

%w(user mod admin).each do |role|
  class_eval <<-RUBY, __FILE__, __LINE__ + 1
    def #{role}?
      role == '#{role}' && roles.include?('#{role}')
    end
  RUBY
end

顺便说一句,在ruby中,
is
前缀是不需要的,因为后面的
告诉程序员,该方法返回
true
false

,您可以用一个ruby代码块定义多个方法

%w(user mod admin).each do |role|
  class_eval <<-RUBY, __FILE__, __LINE__ + 1
    def #{role}?
      role == '#{role}' && roles.include?('#{role}')
    end
  RUBY
end
顺便说一下,在ruby中,
is
前缀是不需要的,因为后面的
告诉程序员该方法返回一个
true
或一个
false

最简单的可能解决方案如下:

class Roles
  def method_missing(method_name, *args, &block)
    if /^is_(?<role_name>\w+)\?$/ =~ method_name
      is_role?(role_name.to_sym)
    else
      super
    end
  end

  private

  def is_role?(role_name)
    # just for demo purposes
    p "Checking #{role_name}"
  end
end

roles = Roles.new

roles.is_user?
roles.is_mod?
roles.is_admin?
最后一件事。在实现
方法\u missing
时,还应注意
响应\u to \u missing?
,这在您想要断言对象是否响应这些神奇方法时非常关键:

有了此功能,您可以执行以下操作:

roles = Roles.new

roles.respond_to? :is_admin? # => true
roles.respond_to? :is_super_user? # => false
阅读更多

希望有帮助

你可以一起去

最简单的可能解决方案如下:

class Roles
  def method_missing(method_name, *args, &block)
    if /^is_(?<role_name>\w+)\?$/ =~ method_name
      is_role?(role_name.to_sym)
    else
      super
    end
  end

  private

  def is_role?(role_name)
    # just for demo purposes
    p "Checking #{role_name}"
  end
end

roles = Roles.new

roles.is_user?
roles.is_mod?
roles.is_admin?
最后一件事。在实现
方法\u missing
时,还应注意
响应\u to \u missing?
,这在您想要断言对象是否响应这些神奇方法时非常关键:

有了此功能,您可以执行以下操作:

roles = Roles.new

roles.respond_to? :is_admin? # => true
roles.respond_to? :is_super_user? # => false
阅读更多



希望有帮助

@Jacob,如果你使用rails 4,你可以使用AR#enum功能(),无需手动实现。

@Jacob,如果你使用rails 4,你可以使用AR#enum功能(),无需手动实现。

我不喜欢
方法u缺失
,因为每次方法调用命中
方法u缺失
,都会导致,它已经爬上了整个祖先链,至少一次。这可能会很贵。谢谢@Aetherus,谢谢您的输入!你说得很对,可能很贵。然而,
method\u missing
是ruby中最基本的元编程方式,因此我正在宣传它。此外,即使它可能很昂贵,我也接受它的“成本”(因为它提供了很大的灵活性),除非我遇到一些真正的性能问题,否则我不会重构它。如果没有,通常我都同意。你是对的。我也从
method\u missing
开始,也许这是在运行时数据不足时实现元编程功能的唯一方法。我不喜欢
method\u missing
,因为每次方法调用点击
method\u missing
,它都已经爬过了整个祖先链,至少一次。这可能会很贵。谢谢@Aetherus,谢谢您的输入!你说得很对,可能很贵。然而,
method\u missing
是ruby中最基本的元编程方式,因此我正在宣传它。此外,即使它可能很昂贵,我也接受它的“成本”(因为它提供了很大的灵活性),除非我遇到一些真正的性能问题,否则我不会重构它。如果没有,通常我都同意。你是对的。我还从
method\u missing
开始,也许这是在运行时之前数据不足的情况下实现元编程功能的唯一方法。第二种方法显然更清楚地看到发生了什么。第一个可能会让团队中的其他人(包括我自己,从现在起一周:)感到困惑。谢谢你关于不要使用
is的建议。我已经从我的代码中删除了它们。第二个显然更清楚地看到发生了什么。第一个可能会让团队中的其他人(包括我自己,从现在起一周:)感到困惑。谢谢你关于不要使用
is的建议。我已经从我的代码中删除了它们。现在我明白你的意思了,这是有道理的。谢谢您的讨论:)没问题:)我建议您把问题中的“函数”改为“方法”。@HunterStevens Done.好的,现在我明白您的意思了,这是有道理的。谢谢您的讨论:)没问题:)我建议您将问题中的“函数”改为“方法”。@HunterStevens完成。我尝试使用枚举,但无法对其使用逐位操作,每个用户可以有多个角色。枚举只支持一个。我尝试使用枚举,但无法对其使用位操作,每个用户可以有多个角色。枚举只支持一个。
roles = Roles.new

roles.respond_to? :is_admin? # => true
roles.respond_to? :is_super_user? # => false