2.2.2 で実行されていた Rails サイトを Rails 3.1 に移行しました。
Rails 3 では、2.2.2 で機能していた save() 呼び出し (INSERTS) が 3.1 では機能しないことに気付きました。
データベースの id フィールドは主キーであるため、次のプロパティがあります。
null
ではない自動インクリメント
これらのテーブルで save() メソッドを実行すると、次のようになります。
ActiveRecord::StatementInvalid (PG::Error: ERROR: null value in column "id" violates not-null constraint
うーん、save() が作成する生成された SQL を調べたところ、実際には列リストに id フィールドが含まれており、nil が割り当てられています。
PG::Error: ERROR: null value in column "id" violates not-null constraint
: INSERT INTO "server_updates" ("action", "created_at", "field_number", "id", "status", "table_number", "value") VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING "id"
それで、私の質問は、save() 呼び出しから SQL を生成するときに ActiveRecord に id 列を含めないようにするにはどうすればよいですか?
もちろん、列から NOT NULL ルールを削除したくはありませんし、生の SQL クエリを使用してこれらの save() 呼び出しをすべて書き換えたくもありません。
モデルに追加set_primary_key "id"
するとこの問題は修正されますが、私には非常に面倒で非レール/ルビーのようです
これを回避するために皆さんは何をしていますか?
助けてくれてありがとう
エラーが発生しているモデルの 1 つを次に示します。
class ServerUpdate < ActiveRecord::Base
def ServerUpdate.run_code code
su = ServerUpdate.new
su.action = 3 # run code
su.value = code
su.status = 1
su.save
end
def ServerUpdate.new_insert_for_table table
su = ServerUpdate.new
su.action = 1 # Create New Record
su.table_number = table.to_i
su.save
return su
end
def ServerUpdate.new_update_for_table_where_field_equals_value table, field, value
su = ServerUpdate.new
su.action = 2 # Update Record
su.table_number = table.to_i
su.field_number = field.to_i
su.value = value.to_s
su.status = 1 ## This used to be in process() method below
su.save
return su
end
def ServerUpdate.new_delete_for_table_where_field_equals_value table, field, value
su = ServerUpdate.new
su.action = 999 # Delete Record
su.table_number = table.to_i
su.field_number = field.to_i
su.value = value.to_s
su.save
return su
end
def set_value_for_field value, field, behavior=0
sui = ServerUpdateItem.new
sui.server_update_id = self.id
sui.field_number = field.to_i
sui.value = value.to_s
b = 0
b = 1 if behavior == "prepend" or behavior == 1
b = 2 if behavior == "append" or behavior == 2
sui.behavior = b
sui.save
end
def process
We are now setting status=1 in method:
ServerUpdate.new_update_for_table_where_field_equals_value table, field, value
self.status = 1
self.save
end
end