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我试图显示Answers作者(User)时,会出现错误,如下所示:

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 次额外的迭代(最后有一个对象)。

要修复它,我只需遍历ticket.answers.length - 1对象。

于 2013-01-16T12:10:02.573 回答