我的Ruby对象中有两个极类似的方法用于Rails应用程序。我知道他们可以合并,我只是不知道如何。 (如果你能找到一种更美妙的方法来处理除return unless
以外的可能的nils,而不是使用#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
答案 0 :(得分: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
。此外,如果您添加更多管理员类型,它是向前兼容的。
答案 1 :(得分:2)
您可以简单地使用collect
,而不是include?
和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?}
答案 2 :(得分: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?”
使用detect而不是collect + include?如果至少找到一个对象将返回一个对象!!双重否定将其变为真/假结果。
我个人只是这样做,因为那资源.user.clinic_memberships.any?在宏伟的计划中没有实际意义:
def is_admin?(resource, kind)
!!resource.user.clinic_memberships.detect { |membership| membership.send("#{kind}_admin?") } if resource.user
end
如果你真的试图防止clin_Mmberships为nil,那么你确实需要条件的下半部分,但是放弃“.any?”,否则你会得到一个错误测试?反对零。
答案 3 :(得分: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?
私有。