0

この問題が長すぎて、どこに問題があるのか​​ わかりません。

    Showing /home/alex/Desktop/personal/app/views/entries/list.html.erb where line #17 raised:

    undefined method `name' for nil:NilClass

Extracted source (around line #17):

14:   <% @entries.each do |entry| %>
15:   <tr>
16:   <td><%= link_to entry.title, :action => "show", :id => entry.id %></td>
17:   <td><%= link_to entry.category.name, :action => "list", :category_id => entry.category.id %></td>
18:   </tr>
19:   <% end %> 
20: 

私の views/entries/list.html.erb は次のようになります。

<html> 
  <head>
    <title>All Entries</title>
  </head>
  <body>

  <h1>Online Personal Collection- All Entries</h1>
  <table border="1">
  <tr>
  <td width="80%"><p align="center"><i><b>Entry</b></i></td> 
   <td width="20%"><p align="center"><i><b>Category</b></i></td>
  </tr>

  <% @entries.each do |entry| %>
  <tr>
  <td><%= link_to entry.title, :action => "show", :id => entry.id %></td>
  <td><%= link_to entry.category.name, :action => "list", :category_id => entry.category.id %></td>
  </tr>
  <% end %> 


  </table>
  <p><%= link_to "Create new entry", :action => "new" %></p>
   <br />
   <%=link_to "Back to Index", entries_path%>
   <br />
   <%=link_to "Back to Account Info", my_account_path%>
   <br />
   <h3>Enter keyword</h3>
<form action ="search" method="post">
<input name = "key" type="input" />
<input value="Send" type="submit"/>
</form>
</body> 
</html>

モデルは次のようなものです。

class Entry < ActiveRecord::Base
  attr_accessible  :comments, :date, :description, :title, :category_id, :category_name
  belongs_to :category
after_create do |entry|
      logger.info "entry created: #{entry.title} #{entry.description}"
end
end




class Category < ActiveRecord::Base
  attr_accessible :name
  has_many :entries
end

そして、entries_controller :

class EntriesController < ApplicationController
  # GET /entries
  # GET /entries.json
  def index

    @entries = Entry.all

    respond_to do |format|
      format.html # index.html.erb
      format.json { render json: @entries }
    end
  end

  def list
      if params[ :category_id].nil?
                  @entries = Entry.find(:all)
          else
              @entries = Entry.find(:all ,
                                :conditions => ["category_id = ?" , params[ :category_id]])
                   params[ :category_id] = nil

      respond_to do |format|
      format.html # list.html.erb
      format.json { render json: @entry }
    end
  end
  end


  # GET /entries/1
  # GET /entries/1.json
  def show
    @entry = Entry.find(params[:id])
    @category = Category.find(:all)


   respond_to do |format|
      format.html # show.html.erb
      format.json { render json: @entry }
    end
  end

  # GET /entries/new
  # GET /entries/new.json
  def new
    @entry = Entry.new
    @categories= Category.find(:all)

    respond_to do |format|
      format.html # new.html.erb
      format.json { render json: @entry }
    end
  end

  # GET /entries/1/edit
  def edit
    @entry = Entry.find(params[:id])
    @categories = Category.find(:all)
  end

  # POST /entries
  # POST /entries.json
  def create
    @entry = Entry.new(params[:entry])
    respond_to do |format|
      if @entry.save
        format.html { redirect_to @entry, notice: 'Entry was successfully created.' }
        format.json { render json: @entry, status: :created, location: @entry }
      else
        format.html { render action: "new" }
        format.json { render json: @entry.errors, status: :unprocessable_entity }
      end
    end
  end

  # PUT /entries/1
  # PUT /entries/1.json

誰かが問題を見つけて、どこが間違っているのかを理解するのを手伝ってくれたら、感謝します。ありがとう!アレックス。

4

1 に答える 1

2

カテゴリのないエントリがあるので、entry.categorynilなので、entry.category.name(この場合)はですnil.name。これは意味がありません。この問題があるため、このような関連付けでメソッドを連鎖させないようにすることをお勧めします。

Railsには、これを防ぐために使用できる組み込みの委任があります。

class Entry < ActiveRecord::Base
  #...
  delegate :name, to: :category, prefix: :category, allow_nil: true
end

これはentry.category_nameインスタンスメソッドを定義します。あなたの見解では、そのエントリのカテゴリが存在しない場合、そこには何も表示されません。委任の方法とオプションについて詳しくは、こちらをご覧ください。

アップデート:

だから私はあなたがnilオブジェクトにリンクしようとしているという事実を無視しました、おそらくあなたが本当にしたいのはオブジェクトがnilのときにリンクをまったく表示しないことです。方法がありますlink_to_if(私はこれまで使用したことはありませんが、おそらくあなたのために働くでしょう):

<%= link_to_if(entry.category, entry.category_name, :action => "list", :category_id => entry.category.id %>

category_name最初の引数がfalseと評価されたときに名前が(リンクなしで)出力されるため、引き続きデリゲートメソッドを使用する必要があります。

于 2012-12-10T19:40:21.660 に答える