grabury
grabury

Reputation: 5559

How to do a better nil check?

I'm getting the following error: 'undefined method `active?' for nil:NilClass'

when I try call

@user.subscription.active?

because sometimes the subscription has not been created yet. I then wrote a method to check if the user had an existing active subscription:

  def active_subscription?
    if !self.subscription.nil?
      if self.subscription.active?
        return true
      else
        return false
      end
    else
      return false
    end
  end

Is there a better way to write this active_subscription? method without all the if else checks and or return statements?

Here is the method in the subscription model checking if the subscription status is active

def active?
 status == 'active'
end

Upvotes: 2

Views: 2890

Answers (5)

With safe navigation you can use @user.subscription&.active

It checks for nil before calling the method.

Upvotes: 1

grandinero
grandinero

Reputation: 1225

def active_subscription?
  subscription && subscription.active?
end

Upvotes: 1

Stefan
Stefan

Reputation: 114178

You can use delegate:

class User < ActiveRecord::Base
  has_one :subscription
  delegate :active?, to: :subscription, prefix: :subscription, allow_nil: true
  # ...
end

Now you can call

user.subscription_active?

It returns subscription.active? (i.e. true or false) if the subscription is available and nil if the association is missing.

Upvotes: 5

Marek Lipka
Marek Lipka

Reputation: 51151

This should be ok:

def active_subscription?
  subscription && subscription.active?
end

or even shorter:

def active_subscription?
  subscription.try(:active?)
end

to ensure the only values this method can return are true and false, you can:

def active_subscription?
  !!subscription.try(:active?)
end

Upvotes: 9

techvineet
techvineet

Reputation: 5111

You can do this

@user.subscription.active? if @user.subscription.present?

Upvotes: 0

Related Questions