Everyone of us saw that kind of error:

NoMethodError: undefined methodstreet' for nil:NilClass`

That means, we are calling street method on nil value, which in our case is users Address, so it means our user might be homeless :o. To prevent it from happening, we can use, :try, &., delegate and rescue, as we are in ruby/rails. Most people would just use delegate or try and even do not think about other options, so lets do some examples.

Lets create simple model, with one associated record – address.

class User < ActiveRecord::Base
  has_one :address
  delegates :street, to: :adress, prefix: false, allow_nil: true
end

class Address < ActiveRecord::Base
  belongs_to :user    
end

Here are how we might get our user street:

eric = User.create(name: 'Eric', email: 'eric@gmail.com')
bob = User.create(name: 'Bob', email: 'homeless@gmail.com')
eric.create_address(city: 'Bialystok', street: 'the street')

Chaining methods

User.each do |user|
  p user.address.street
end

eric # the street

bob # NoMethodError

PROS:
- easy to write
- easy to read

CONS:
- might crush our whole website
- violates law of demeter

Using try / &.

User.each do |user|
  p user.address.try(:street)
end

eric # the street

bob # nil

PROS:
- do not crush our website
- :try might be chained
- we do not have to write any methods in models

CONS:
- does not look pretty

Using delegate

User.each do |user|
  user.street
end

eric # the street

bob # nil

PROS:
- look very good
- does not crush our website
- we can delegate delegated methods – but it is not recommended
- we can add prefix to our delegated method

CONS:
- for the begginer might looks hard to use

Using rescue

User.each do |user|
  p user.street rescue nil
end

eric # the street

bob # nil

PROS:
- it works | bad performance
- just dont use it - there are better ways for this job

CONS:
- bad performance

And finally, SQL way!

User
 .joins('LEFT JOIN addresses ON addressess.user_id = users.id')
 .select('addresses.street street').each do |user|
  p user[:street]
end

eric # the street

bob # nil

PROS:
- with this way we are not dependent on rails / ruby methods
- we can create custom aliases, for example user[:best_street]
- we are 100% sure we will not crush our website
- we can work on hundreds of associations without polluting models with hunders of delegations

CONS:
- might be hard if someone does not know sql
- we have to use raw sql left join, in rail 5 it will change
- kinda overjob in small cases

I have described all ways of solving nil association problem that I know, I hope that the last one will give you some thinking, if you have any other ways fighting nil, just write a comment!

Thanks for reading, cya next post !