今日、私のエラーは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 回余分に反復しているようです。