gpt4 book ai didi

ruby-on-rails - Rails 行为不当 wrt Postgres SERIAL NOT NULL 专栏

转载 作者:行者123 更新时间:2023-11-29 11:34:43 27 4
gpt4 key购买 nike

我正在开发一个(当前)带有 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 值和/或将其识别为与“设置为默认值”相同?

我会尝试只猴子修补 Rails 2.3.x ActiveRecord 内部结构,但我知道如果我这样做的话,在过渡到 Rails 3 时我会被搞砸了。

我研究过尝试在插入之前使用 PL/pgSQL 触发器修复问题,但我无法弄清楚如何使用 PL/pgSQL 告诉 PostgreSQL“取消定义”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

关于ruby-on-rails - Rails 行为不当 wrt Postgres SERIAL NOT NULL 专栏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3919972/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com