Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby: Combine two similar methods into one?

I have two extremely similar methods in my Ruby object for a Rails app. I know they can be combined, I just don't know how. (Extra points if you can find a more beautiful way to handle possible nils besides return unless, not using #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
like image 325
nickcoxdotme Avatar asked May 09 '26 15:05

nickcoxdotme


2 Answers

How about:

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

If someone gives a nonexistent type, it'l throw NoMethodError. Also, it's forward compatible if you add more admin types.

like image 62
Linuxios Avatar answered May 11 '26 07:05

Linuxios


Instead of your collect and include? mechanism, you can simply use any?. If clinic_memberships always return an array (which it does if it is e.g. a has_many association), you don't even need to check that.

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

This can then be called like

has_membership?(resource, &:portal_admin?)

which is equivalent to

has_memberhsip?(resource){|m| m.portal_admin?}
like image 31
Holger Just Avatar answered May 11 '26 07:05

Holger Just