When developing a Ruby on Rails application that involves a user having one address, and the address table having all the address values such address_line_1, address_line_2, etc., the details may need to be shown similar to this:
1
<%= @user.address.address_line_1 %>
It can be easy to overlook the fact that this is not taking the address of the user as a registration step, but rather allowing the user to register, and after successful registration, to add details to their profile any time.
This can break the code when testing for a user that has no address. The error may look like this:
1
NoMethodError (undefined method `address_line_1' for nil:NilClass)
As a response to this:
1
<%= @user.address.address_line_1 %>
An expert solution to this issue is Safe Navigation Operator. Here is a working example:
Create an Application
Create a new Rails application.
1
2
rails new safe_navigation_operator
rails db:create
Generate Models
Generate two models, i.e. User and Address.
1
2
rails generate model user email
rails generate model address address_line_1
Add this line to db/migrate/abc_create_addresses.rb
file:
1
t.belongs_to :user
1
rails db:migrate
Define Relationships
In user.rb
, add this line:
1
has_one :address
In address.rb
, add this line:
1
belongs_to :user, optional: true
Inserting Records
Now add some records in our database for the open rails console. Run rails console
for your root folder.
1
2
3
4
5
User.create(email: 'test@gmail.com')
User.create(email: 'test_with_password@gmail.com', password: '123456')
u2.create_address(address_line_1: "Lahore")
Testing
1
2
3
4
5
u2.address.address_line_1
=> "Lahore"
u1.address.address_line_1
=> NoMethodError (undefined method `address_line_1' for nil:NilClass)
Solution
1
2
u1.address&.address_line_1
=> nil
This will handle the error efficiently and cleanly.