3

对于 Rails 应用程序,我的 Ruby 对象中有两个极其相似的方法。我知道它们可以组合,我只是不知道如何。(如果你能找到一种更漂亮的方法来处理可能的 nils return unless,而不是使用 ,则加分#try。)

 def is_portal_admin?(resource)
    return unless resource.user && resource.user.clinic_memberships.any?
    memberships = resource.user.clinic_memberships.collect { |membership| membership.portal_admin? }
    memberships.include?(true)
  end

  def is_staff_admin?(resource)
    return unless resource.user && resource.user.clinic_memberships.any?
    memberships = resource.user.clinic_memberships.collect { |membership| membership.staff_admin? }
    memberships.include?(true)
  end
4

4 回答 4

3

怎么样:

def is_admin_of_type?(type, resource)
  return unless resource.user && resource.user.clinic_memberships.any? && type
  memberships = resource.user.clinic_memberships.collect { |membership| membership.send("#{type}_admin?") }
  memberships.include?(true)
end

如果有人给出一个不存在的类型,它会抛出NoMethodError. 此外,如果您添加更多管理员类型,它是向前兼容的。

于 2013-03-21T21:51:31.520 回答
2

而不是你的collectandinclude?机制,你可以简单地使用any?. 如果clinic_memberships总是返回一个数组(如果它是一个has_many关联,它会这样做),你甚至不需要检查它。

def has_membership?(resource, &block)
  return unless resource.user
  resource.user.clinic_memberships.any?(&block)
end

然后可以这样调用

has_membership?(resource, &:portal_admin?)

这相当于

has_memberhsip?(resource){|m| m.portal_admin?}
于 2013-03-21T21:59:12.627 回答
0
def is_admin?(resource, kind)
  if resource.user && resource.user.clinic_memberships.any?
    !!resource.user.clinic_memberships.detect { |membership| membership.send("#{kind}_admin?") }
  end
end

如果您不进入 if 分支,则返回 nil,因此执行上述条件将产生与显式返回相同的结果,除非...

添加第二个参数并传递 :staff 或 :portal(或“staff”或“portal”)。使用“send”将在运行时评估为“staff_admin?” 或“portal_admin?”

使用检测而不是收集+包含?如果至少找到一个对象并且 !! 双重否定将其变成真/假结果。

自从resource.user.clinic_memberships.any?在宏伟的计划中没有实际意义:

def is_admin?(resource, kind)
  !!resource.user.clinic_memberships.detect { |membership| membership.send("#{kind}_admin?") } if resource.user
end

如果您实际上是在尝试防止 Clinic_memberships 为 nil,那么您确实需要条件的第二半,但删除“.any?”,否则您会得到一个错误测试 any?反对零。

于 2013-03-21T22:03:16.817 回答
0
def is_portal_admin?(resource)
  is_admin_of_type?(resource, :portal)
end

def is_staff_admin?(resource)
  is_admin_of_type?(resource, :staff)
end

def is_admin_of_type?(resource, type)
  if (user = resource.user)
    user.clinic_memberships.any? { |ms| ms.send("#{type}_admin?") }
  end
end
  • 检查是否有memberships.
  • 您可以在|| false条件后添加,以确保您method?返回布尔值。
  • 你可以设为is_admin_of_type?私有。
于 2013-03-21T22:13:18.930 回答