NoMethodError: undefined method `debug' for nil:NilClass
ActiveRecord のテスト(unit/test)をしていて以下のエラーが発生しました。
test_1(TestSession): NoMethodError: undefined method `debug' for nil:NilClass /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/base.rb:2313:in `remove_attributes_protected_from_mass_assignment' /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/base.rb:2114:in `attributes=' /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/base.rb:1926:in `initialize' test_session.rb:25:in `new' test_session.rb:25:in `test_1'
環境は以下のとおり。
■DBスキーマ(sessionsテーブル)
CREATE TABLE sessions ( session_id VARCHAR(255) NOT NULL PRIMARY KEY, data TEXT NOT NULL, created_on DATETIME NOT NULL );
■モジュール(DB::Session)
require 'rubygems' require 'active_record' ActiveRecord::Base.establish_connection( :adapter => 'sqlite3', :database => '/foo/var/db/database.sqlite3' ) module DB class Session < ActiveRecord::Base set_primary_key "session_id" end end
■テストケース(test_session.rb)
・ソース
require 'test/unit' require 'db/session' class TestSession < Test::Unit::TestCase def setup end def teardown end def delete(value) obj = Uploader::DB::Session.find(:first, :conditions => ["session_id = ?", value]) obj.destroy if obj != nil end def test_1 session_id = '__session_id_test_1__' data = 'hoge' now = Time.now.strftime("%Y-%m-%d %H:%M:%S") # 前処理 self.delete(session_id) # Insert成功パターン session = DB::Session.new(:session_id => session_id, :data => data, :created_on => now) assert_equal(true, session.save) # 後処理 self.delete(session_id) end
・実行結果
1) Error: test_1(TestSession): NoMethodError: undefined method `debug' for nil:NilClass /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/base.rb:2313:in `remove_attributes_protected_from_mass_assignment' /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/base.rb:2114:in `attributes=' /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/base.rb:1926:in `initialize' test_session.rb:25:in `new' test_session.rb:25:in `test_1'
■原因
ActiveRecord の プライマリーキーに auto_increment な INTEGER型のカラムではなく、
VARCHAR型を使用したために ActiveRecord オブジェクトのインスタンス生成でこけた模様。
〇改善方法
sessions テーブルに id カラムを PRIMARY KEY として定義する。
DB::Sessionモジュールの PRIMARY KEY 名設定を削除する。
■DBスキーマ(sessions テーブル)
CREATE TABLE sessions ( + id INTEGER NOT NULL PRIMARY KEY, + session_id VARCHAR(255) NOT NULL PRIMARY KEY, - session_id VARCHAR(255) NOT NULL UNIQUE, data TEXT NOT NULL, created_on DATETIME NOT NULL );
■モジュール(DB::Session)
require 'rubygems' require 'active_record' ActiveRecord::Base.establish_connection( :adapter => 'sqlite3', :database => '/foo/var/db/database.sqlite3' ) module DB class Session < ActiveRecord::Base - set_primary_key "session_id" end end