ruby-on-rails – Rails行为错误的Postgres SERIAL NOT NULL列
我正在开发一个带有PostgreSQL 8.4数据库后端的(当前)Rails 2.3.x应用程序.在我的Rails应用程序中,我有一个对应于数据库表的模型,该数据库表有两列数据类型SERIAL并设置为NOT NULL.我将这些列中的一个设置为Rails中的主键和PostgreSQL约束.
表定义: CREATE TABLE problem_table ( col1 serial NOT NULL,col2 serial NOT NULL,other_col1 character varying,other_col2 character varying,...,CONSTRAINT problem_table_pkey PRIMARY KEY (col1) ); 模型类定义: class ModelClass1 < ActiveRecord::Base self.table_name = 'problem_table' self.primary_key = 'col1' end 我的问题是关于非主键SERIAL NOT NULL列.当我尝试执行Rails ActiveRecord :: Base#create时,Rails正确地没有为主键SERIAL NOT NULL列设置一个值,而是为另一个设置了一个NULL值的列值,这导致PostgreSQL抱怨NOT NULL列被设置为NULL. 我告诉Rails做什么: ModelClass1.create( other_col1: 'normal' other_col2: 'data',... ); Rails告诉PostgreSQL: INSERT INTO problem_table ( col2,other_col1,other_col2,... ) VALUES ( NULL,'normal','data',... ); 我的问题是,如何让Rails停止为此列传递NULL并且不传递任何内容,让DEFAULT nextval(my_seq)接管?或者,如果这不可能,我怎么能告诉PostgreSQL在传递时忽略这个NULL值和/或认识到它与’设置为DEFAULT’相同? 我会尝试只是猴子补丁Rails 2.3.x ActiveRecord内部,但我知道如果我这样做,我会被拧到过渡到Rails 3. 我试着用INSFORE INSF中的PL / pgSQL触发器来解决问题,但是我无法弄清楚如何告诉PostgreSQL PL / pgSQL“取消定义”NEW.col2值或者说NEW.col2:= DEFAULT (这不起作用). 答案和/或建议表示赞赏! 解决方法
更简单的方法是定义自己的序列,并在ActiveRecord回调中使用Postgres自己的nextval(). nextval()处理在一个原子操作中向前推进序列一步,并返回下一个值.
在迁移中: def self.up execute "CREATE SEQUENCE myseq" end def self.down execute "DROP SEQUENCE myseq" end 在模型中: before_save :set_column_from_sequence,:on => :create def set_column_from_sequence self.mycolumn = self.class.connection.select_value("SELECT nextval('myseq')") end (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |