Reputation: 660
I have a Topic which has_many Posts. Each Post belongs to a User, and each User has_one Profile.
In my "show" page for a specific Topic, I try to display profile information of the user who created the post:
<% @topic.posts.each do |post| %>
<%= post.user.profile.first_name %>
<% end %>
I get the following error:
undefined method `profile' for nil:NilClass
Any idea why it does not allow me to access the profile? Please advise.
My Topic controller is as follows:
class TopicsController < ApplicationController
# GET /topics
# GET /topics.json
add_breadcrumb :index, :topics_path
def index
if params[:tag]
@topics = Topic.tagged_with(params[:tag])
else
@topics = Topic.all
end
@newtopic = Topic.new
respond_to do |format|
format.html # index.html.erb
format.json { render json: @topics }
end
end
# GET /topics/1
# GET /topics/1.json
def show
@topic = Topic.find(params[:id])
@posts = @topic.posts
@newpost = @topic.posts.build
add_breadcrumb @topic.name
respond_to do |format|
format.html # show.html.erb
format.json { render json: @topic }
end
end
# GET /topics/new
# GET /topics/new.json
def new
add_breadcrumb :new, :topics_path
@topic = Topic.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: @topic }
end
end
# GET /topics/1/edit
def edit
@topic = Topic.find(params[:id])
end
# POST /topics
# POST /topics.json
def create
@topic = Topic.new(params[:topic])
@topic.user_id = current_user.id
@topic.last_poster_id = current_user.id
@topic.last_post_at = Time.now
respond_to do |format|
if @topic.save
format.html { redirect_to @topic, notice: 'Topic was successfully created.' }
format.json { render json: @topic, status: :created, location: @topic }
else
format.html { render action: "new" }
format.json { render json: @topic.errors, status: :unprocessable_entity }
end
end
end
# PUT /topics/1
# PUT /topics/1.json
def update
@topic = Topic.find(params[:id])
respond_to do |format|
if @topic.update_attributes(params[:topic])
format.html { redirect_to @topic, notice: 'Topic was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: @topic.errors, status: :unprocessable_entity }
end
end
end
# DELETE /topics/1
# DELETE /topics/1.json
def destroy
@topic = Topic.find(params[:id])
@topic.destroy
respond_to do |format|
format.html { redirect_to topics_url }
format.json { head :no_content }
end
end
end
Upvotes: 0
Views: 71
Reputation: 29599
Your error is caused by this line in the show action @topic.posts.build
and this line in the view @topic.posts.each
. Since you are building a new post in the controller, @topic.posts
includes that new record which most probably have the user as nil. So the solution to your problem is to use @posts
instead of @topic.posts
in your view.
Upvotes: 1
Reputation: 23356
Check your database. Its very likely that in your database there is a post which corresponds to no user. Since the user for that post is none, the profile becomes undefined for nil:NilClass
which is user(null).
This happens mostly when you creates the post that belongs to user but then you deletes the user that belongs to that post from database.
The correct way is to impose a constraint in your user model that should be-
class Post
belongs_to :user, :dependent => :destroy
end
So if the user gets deleted, the corresponding posts of that user also get deleted.
Please note that it is not a good practice to directly delete records from database after imposing the relationship between them using tables.
Upvotes: 1