How to apply Null object pattern for ActiveRecord associations?

Say we have have some “belongs_to” association on the User model:

class User < AR
  belongs_to :company
end

In some place of the application I want to use this code with confidence: “user.company.name”.

According to the “Null object” pattern we could achieve the result by defining the “belongs_to” method directly:

class NullCompany
    def name
      'Unnamed'
    end
end

class User < AR
  belongs_to :company

  def company
    @company || NullCompany.new
  end
end

But redefining the associations on active record models is bad practice and may lead to unexpected behavior or broken code.
We can use here delegate Rails’ method with “prefix” and “allow_nil” option. But it seems like a kludge either.
So, how to apply “Null object” pattern in such situations? Or is there any other good solution for this?

I think this will work without surprising effects:

def company
  super || NullCompany.new
end
4 Likes

In Rails 4 , Has some surprising effects indeed. Specially for active record provided methods . Like find_by_some_attr

def find_by_some_attribute(attribute_value)
  super || NullRewardFee.new
end

If we check in rails console It works for the first call into the method but not the following ones . The second call to the method onwards would return nil .Still have not figured out why though .

Hi @PeytonF18 I think you’re right that redefining a finder method is probably a dangerous behavior. I think what @benorenstein defined above for just defining the company association looks safe.

If you’re feeling squeamish about redefining an association (remember they are just macros!), you can always write these out as explicit association methods:

def company_or_missing
   company || NullCompany.new
end