user4560335
user4560335

Reputation:

How to access attributes of associated resource in view through Devise's user model?

I am experiencing issues while trying to display user profile attributes in a view, using Devise. This is just to display the value, I am not even trying to update it yet, so I believe that there is no need of strong parameters.

Here are my models:

# user.rb
class User < ActiveRecord::Base
  has_one :profile
end

and

# profile.rb
class Profile < ActiveRecord::Base
  belongs_to :user
end

Here is my controller:

# users_controller.rb
class Admin::UsersController < AdminController
  def index
    @users = User.all.order('id ASC')
  end
end

Here is my view:

# index.html.erb
<% if @users.present? %>
  <p><%= @users.first.profile.first_name %></p>

  <ul>
    <% @users.each do |user| %>
      <li><%= user.profile.first_name %></li>
    <% end %>
  </ul>
<% end %>

Now while <%= @users.first.profile.first_name %> outside of the "each" loop works well and returns the value, <%= @users.first.profile.first_name %> inside the loop returns the following error:

NoMethodError: undefined method `first_name' for nil:NilClass

I came to the conclusion that this is down to Devise and how it allows you to access any associated records outside of its own controller. For the record, I tried the same code for other resources and it worked as expected.

Any help on this would be really appreciated!

Upvotes: 1

Views: 462

Answers (1)

Rustam Gasanov
Rustam Gasanov

Reputation: 15781

You loop through users and call .profile.first_name, but some of your users don't have .profile, ie it is nil, thats why you receive:

NoMethodError: undefined method `first_name' for nil:NilClass

Simply replace

<li><%= user.profile.first_name %></li>

with

<li><%= user.profile.try(:first_name) %></li>

.try will return nil instead exception raising if user's .profile doesn't exist

Alternatively handle it yourself/show some message:

<li><%= user.profile.present? ? user.profile.first_name : "Profile doesn't exist" %></li>

Upvotes: 2

Related Questions