简体   繁体   中英

How do I access an associated model of an associated model?

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

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM