Reputation:
I am having a problem:
<% @post.each do |post| %>
<%=link_to post.title, post %>
<p>Published
<%= time_ago_in_words(post.created_at) %> ago by
<%= post.user.user_name %></p>
<% end %>
The user name doesn't display it stays just blank in the webpage while if i type:
<%= post.user.email%>
It works the email displays. I don't understand why the user_name
isn't showing up and for me it makes no sense. I am using the weBrick server for development if you need to now.
Upvotes: 0
Views: 40
Reputation: 76774
It probably means you don't have user_name
present in the associative user field, although if it was missing completely, it would normally throw an exception.
I'd say the record is blank or NULL in the db, hence it has no actual value when you output it.
The way to resolve is to make sure you're storing the value in your db. Rails has validations
for this purpose:
#app/models/user.rb
class User < ActiveRecord::Base
validates :user_name, presence: true
end
This will fire each time you create
or update
a user record, which means that when you send params like in your comments...
#<User id: 1, user_name: nil, full_name: nil, email: "[email protected]", password_digest: "$2a$10$wLxvI3RYjjIY2lmga0irU.Rlf0pwCM6/HlsgbI10eb1...", role: nil, created_at: "2015-12-25 09:39:37", updated_at: "2015-12-25 09:39:37">
... it will come back with an error that you cannot create the record because user_name
is not present.
In situations like this, we use a method to fall back onto the email if the name
doesn't exist:
#app/models/user.rb
class User < ActiveRecord::Base
def user_name
self[:user_name] || email
end
end
This allows you to call @user.name
and if they don't have it, it pulls the email
instead.
This way, if you validate on having the email present, you'll be able to always return a value.
--
Another cool trick is delegate
, which avoids the law of demeter
(IE only have one point when calling attributes):
#app/models/post.rb
class Post < ActiveRecord::Base
delegate :user_name, to: :user
end
This will allow you to call:
<%= post.user_name %>
... with it calling the user_name
attribute from the User
model.
Upvotes: 1