0

今日、私のエラーはCalled id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id.

私はモデルとコントローラーを持っています:ユーザー、チケット、アンサーはそのように定義されています:

UserたくさんありますAnswers&Tickets

Ticket多くを持っていますAnswers

Answer属しているUser& 属しているTicket

ビューで著者()を次のようTicketに表示しようとすると、エラーが表示されます。AnswersUser

Ticket Load (0.2ms) SELECT "tickets".* FROM "tickets" LIMIT 1 => #<Ticket id: 8, topic: "This is sample question", message: "This is Sample question with <h1>Some</h1> HTML! <p...", user_id: 1, category_id: 2, created_at: "2013-01-15 12:24:20", updated_at: "2013-01-15 12:24:20", answers_count: 1>

Answer Load (0.2ms) SELECT "answers".* FROM "answers" LIMIT 1 => #<Answer id: 6, ticket_id: 8, user_id: 1, message: "This is answer to the sample question with use of h...", created_at: "2013-01-15 12:26:46", updated_at: "2013-01-15 12:26:46">

User Load (0.2ms) SELECT "users".* FROM "users" LIMIT 1 => #<User id: 1, username: "mickula", email: "xx@xx.com", password_hash: "$2a$10$Hty2ekM3t8Dqf0CvZm5zEOwVnXAoytimW9tIOxtfjwNG...", password_salt: "$2a$10$Hty2ekM3t8Dqf0CvZm5zEO", created_at: "2013-01-12 16:55:00", updated_at: "2013-01-12 16:55:00", permission_level: nil>

User.first.answers
  User Load (0.2ms)  SELECT "users".* FROM "users" LIMIT 1
  Answer Load (0.1ms)  SELECT "answers".* FROM "answers" WHERE "answers"."user_id" = 1
 => [#<Answer id: 6, ticket_id: 8, user_id: 1, message: "This is answer to the sample question with use of h...", created_at: "2013-01-15 12:26:46", updated_at: "2013-01-15 12:26:46">] 

回答を表示しようとすると、a.user.usernameエラーが返されます:

undefined method username for nil:NilClass

したがって、その答えはユーザーに関連付けられていないようです。どこで間違えたのか、なぜそのように振る舞うのか教えていただけますか? チケットに対してこのようにしたことを言及したいと思います。そこで、チケットの作成者を表示できます @ticket.user.username

モデル:

class Ticket < ActiveRecord::Base
  attr_accessible :topic, :message, :user, :category, :category_id
  has_many :answers
  belongs_to :user
  belongs_to :category

end

class Answer < ActiveRecord::Base
  attr_accessible :ticket, :user, :message
  belongs_to :user
  belongs_to :ticket, :counter_cache => true
end

class User < ActiveRecord::Base
  attr_accessible :username, :email, :password, :password_confirmation
  has_many :tickets
  has_many :answers
end

コントローラーのパーシャル:

class TicketsController < ApplicationController
  before_filter :login_required
  before_filter :admin_required, :only => [:index, :show]
  def index
    @tickets = Ticket.all
  end

  def show
    @ticket = Ticket.find(params[:id])
  end
end

class AnswersController < ApplicationController
  def create
    t_attr = params[:answer].merge :user => current_user
    @ticket = Ticket.find(params[:ticket_id])
    @answer = @ticket.answers.create(t_attr)
    redirect_to ticket_path(@ticket)
  end
end

編集:コンソールを介して、回答の作成者ユーザーデータを取得できます:

Ticket.first.answers.first.user
  Ticket Load (0.2ms)  SELECT "tickets".* FROM "tickets" LIMIT 1
  Answer Load (0.1ms)  SELECT "answers".* FROM "answers" WHERE "answers"."ticket_id" = 8 LIMIT 1
  User Load (0.1ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1
 => #<User id: 1, username: "mickula", email: "xx@xx.com", password_hash: "$2a$10$Hty2ekM3t8Dqf0CvZm5zEOwVnXAoytimW9tIOxtfjwNG...", password_salt: "$2a$10$Hty2ekM3t8Dqf0CvZm5zEO", created_at: "2013-01-12 16:55:00", updated_at: "2013-01-12 16:55:00", permission_level: nil> 

チケット ビュー:

<span class="pull-right">by  <strong><%=h @ticket.user.username %></strong> on  <i><%=h @ticket.created_at %> in <strong><%= @ticket.category.name %></strong></i></span>



<p>
  <strong>Message:</strong><br>
  <%=h @ticket.message %> 
</p>
<h3>Replies</h3>
<%= form_for([@ticket, @ticket.answers.build]) do |f| %>
    <%= f.label :message %> <br>
    <%= f.text_area :message, :cols => "50", :rows => "6", :class=> "span12" %><br>
    <%= f.submit %>
<% end %>
<% @ticket.answers.each do |a| %>
    <%= h a.message %> <%= a.user.username %> <%= a.created_at %>
<% end %>
</div>

回避策:

    <% @ticket.answers.each do |a| %>
    <%= h a.message %> <%= a.user.username if a.user %> <%= a.created_at %>
<% end %>

この条件では、すべてが機能します。答えがない場合でも、Loop は 1 回余分に反復しているようです。

4

1 に答える 1

0

Rails の足場は、このために新しい空のオブジェクトを作成します。

<%= form_for([@ticket, @ticket.answers.build]) do |f| %>

回答コントローラーで指定されているように、検証が失敗した後に入力されたフォーム入力を表示するなどのフォーム操作を実行します (ユーザーがフォームフィールドに入力されたデータを失うことはありません)。

  def create
    t_attr = params[:answer].merge :user => current_user
    @ticket = Ticket.find(params[:ticket_id])
    @answer = @ticket.answers.create(t_attr)
    redirect_to ticket_path(@ticket)
  end

このループのため、余分な反復が 1 回実行されていました (最後に 1 つのオブジェクトを使用)。

ticket.answers.length - 1それを修正するには、オブジェクトを反復処理するだけです。

于 2013-01-16T12:10:02.573 に答える