以下代码创建表而不引发任何错误:
CREATE TABLE test(
ID INTEGER NULL,
CONSTRAINT PK_test PRIMARY KEY(ID)
)
Run Code Online (Sandbox Code Playgroud)
请注意,我无法按预期插入NULL:
INSERT INTO test
VALUES(1),(NULL)
ERROR: null value in column "id" violates not-null constraint
DETAIL: Failing row contains (null).
********** Error **********
ERROR: null value in column "id" violates not-null constraint
SQL state: 23502
Detail: Failing row contains (null).
Run Code Online (Sandbox Code Playgroud)
为什么我可以创建一个具有自相矛盾定义的表格?ID列显式声明为NULLable,并且作为PRIMARY KEY的一部分,它隐式地不可为空.是否有意义?
编辑:如果这个自相矛盾的CREATE TABLE在那里失败了会不会更好?
我有一个我想创建的对象,可以在我的一个模型中访问.我把他放在哪里?我担心如果我把他放在模型类文件中,每次我创建该模型的新实例时都会创建它.我只想在启动时创建一次这个对象.这是对象:
require 'pubnub'
publish_key = 'fdasfs'
subscribe_key = 'sdfsdsf'
secret_key = 'fsdfsd'
ssl_on = false
pubnub_obj = Pubnub.new(publish_key,
subscribe_key,
secret_key,
ssl_on)
Run Code Online (Sandbox Code Playgroud)
我在模型中使用他这样:
class Message < ActiveRecord::Base
def self.send_new_message_client(message)
message = { 'some_data' => message }
info = pubnub_obj.publish({
'channel' => 'testing',
'message' => message
})
puts(info)
end
end
Run Code Online (Sandbox Code Playgroud) 我有一张桌子,我只想要一个入口.因此,如果有人试图插入另一行,则只有在有人删除了以前存在的行之后才允许这样做.
如何为这样的表设置规则?
在典型的Rails(4.2.x)博客应用程序中,我有一个Post模型。该帖子具有一个称为primary的布尔列。我想强制执行一个模型级别的约束,即至多一个帖子具有primary = true。如果用户将新帖子设置为primary = true,则在保存此帖子之前,所有其他帖子都必须标记为primary = false。
当帖子创建或更新为primary = true时,我可以在控制器中执行此操作,方法是将所有其他帖子更改为primary = false。就像是:
# in posts_controller#create and #update
...
if @post.primary
[Post.all - self].select(&:primary).each do {|p|p.primary = false; p.save}
end
@post.save!
...
Run Code Online (Sandbox Code Playgroud)
但是,我希望这是一个模型级别的约束,因此我可以添加验证,单元测试等,以确保只有一个帖子具有primary = true。如果我使用类似before_commit的回调,那么我可能会陷入无限循环,因为更新新帖子的before_commit中的旧帖子会触发旧帖子的before_commit等。
如何在模型级别强制执行此行为?