I have a model spec that is failing with "undefined method 'save' for nil:NilClass'." This occurs in the class method 'create_and_send_self_eval'. The method is creating a new Evaluation, but it always returns nil in the test environment. I've also tried using 'create', 'create!' and they also return nil. However, this only occurs in the test environment. In the development environment, it returns the correct object. I'm using rspec 3.1.5, rails 4.1.6, and ruby 2.1.2.
I've included the code for the class and my debug output. Any suggestions?
Evaluation.rb
class Evaluation < ActiveRecord::Base
has_one :evaluator
validates_uniqueness_of :access_key
validates_presence_of :participant_id
before_validation :set_access_key, on: :create
def send_invite
return true
end
def self.create_and_send_self_eval(participant)
evaluation = self.new do |e|
e.participant_id = participant.id
e.evaluator = participant
end
if evaluation.nil?
binding.pry
end
evaluation.save
end
private
def set_access_key
return if access_key.present?
begin
self.access_key = SecureRandom.hex(8)
end while self.class.exists?(access_key: self.access_key)
end
end
Debug output using pry in the test environment
[1] pry(Evaluation)> participant
=> #<Participant id: 167, first_name: "Puff", last_name: "Daddy", evaluation_url: nil, created_at: "2014-10-07 19:43:47", updated_at: "2014-10-07 19:43:47">
[2] pry(Evaluation)> Evaluation.new
=> nil
[3] pry(Evaluation)> Evaluation.create(participant_id: participant.id)
NoMethodError: undefined method `save' for nil:NilClass
from /Users/diyahm/.rvm/gems/ruby-2.1.2/gems/activerecord-4.1.6/lib/active_record/persistence.rb:34:in `create'
[4] pry(Evaluation)> Evaluation.create!(participant_id: participant.id)
NoMethodError: undefined method `save!' for nil:NilClass
from /Users/diyahm/.rvm/gems/ruby-2.1.2/gems/activerecord-4.1.6/lib/active_record/validations.rb:41:in `create!'
Debug output in rails console
2.1.2 :005 > p = Participant.last
SQL (0.9ms) SELECT "participants"."id" AS t0_r0, "participants"."first_name" AS t0_r1, "participants"."last_name" AS t0_r2, "participants"."evaluation_url" AS t0_r3, "participants"."created_at" AS t0_r4, "participants"."updated_at" AS t0_r5, "evaluators"."id" AS t1_r0, "evaluators"."email" AS t1_r1, "evaluators"."created_at" AS t1_r2, "evaluators"."updated_at" AS t1_r3, "evaluators"."actable_id" AS t1_r4, "evaluators"."actable_type" AS t1_r5, "evaluators"."evaluation_id" AS t1_r6 FROM "participants" LEFT OUTER JOIN "evaluators" ON "evaluators"."actable_id" = "participants"."id" AND "evaluators"."actable_type" = 'Participant' ORDER BY "participants"."id" DESC LIMIT 1
=> #<Participant id: 3, first_name: "Puff", last_name: "Daddy", evaluation_url: nil, created_at: "2014-10-06 06:32:40", updated_at: "2014-10-06 06:32:40">
2.1.2 :006 > Evaluation.new
=> #<Evaluation id: nil, participant_id: nil, access_key: nil, created_at: nil, updated_at: nil>
2.1.2 :007 > Evaluation.create(participant_id: p.id)
(0.2ms) BEGIN
Evaluation Exists (2.1ms) SELECT 1 AS one FROM "evaluations" WHERE "evaluations"."access_key" = 'c688b05ee4625c60' LIMIT 1
Evaluation Exists (0.3ms) SELECT 1 AS one FROM "evaluations" WHERE "evaluations"."access_key" = 'c688b05ee4625c60' LIMIT 1
SQL (1.7ms) INSERT INTO "evaluations" ("access_key", "created_at", "participant_id", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["access_key", "c688b05ee4625c60"], ["created_at", "2014-10-07 19:47:15.877706"], ["participant_id", 3], ["updated_at", "2014-10-07 19:47:15.877706"]]
(2.3ms) COMMIT
=> #<Evaluation id: 4, participant_id: 3, access_key: "c688b05ee4625c60", created_at: "2014-10-07 19:47:15", updated_at: "2014-10-07 19:47:15">
pry debug output at beginning of method
[1] pry(Evaluation)> self
=> Evaluation(id: integer, participant_id: integer, access_key: string, created_at: datetime, updated_at: datetime)
[2] pry(Evaluation)> self.class
=> Class
[3] pry(Evaluation)> self.connection
=> #<ActiveRecord::ConnectionAdapters::PostgreSQLAdapter:0x007f8158eb8ee0
[4] pry(Evaluation)> Evaluation
=> Evaluation(id: integer, participant_id: integer, access_key: string, created_at: datetime, updated_at: datetime)
[5] pry(Evaluation)> Evaluation.class
=> Class
[6] pry(Evaluation)> Evaluation.connection
=> #<ActiveRecord::ConnectionAdapters::PostgreSQLAdapter:0x007f8158eb8ee0
I didn't show the entire output for self.connection or Evaluation.connection. But connection is returning correctly.