ruby-on-rails - 创建表时如何防止 rails 在 schema.rb 中插入 `id: :integer`?

标签 ruby-on-rails ruby postgresql ruby-on-rails-5

最近我在创建新记录时开始遇到某些模型的错误:

PG::NotNullViolation: ERROR: null value in column "id" violates not-null constraint

这不会发生在所有模型上,但只是其中一些,而且并不总是立即发生。经过一些检查后,我意识到当表创建行的 schema.rb 文件中出现“id: :integer”时出现错误。

这是创建非错误表的迁移示例:

class CreateArticles < ActiveRecord::Migration[5.0]
  def change
    create_table :articles do |t|
      t.string :main_title
      t.boolean :published
      t.string :short_title
      t.text :a_body
      t.string :a_image

      t.timestamps
    end
  end
end

这是在 schema.rb 中显示的内容:

create_table "articles", force: :cascade do |t|
  t.string   "main_title"
  t.boolean  "published"
  t.string   "short_title"
  t.text     "a_body"
  t.string   "a_image"
  t.datetime "created_at",         null: false
  t.datetime "updated_at",         null: false
  t.string   "slug"
  t.string   "a_meta_title"
  t.string   "a_meta_description"
  t.string   "a_other"
  t.string   "a_comment"
  t.index ["slug"], name: "index_articles_on_slug", using: :btree
end

现在对“代理”进行同样的操作:

class CreateAgents < ActiveRecord::Migration[5.0]
  def change
    create_table :agents do |t|
      t.boolean :status
      t.string :stripeId
      t.integer :UserID

      t.timestamps
    end
  end
end

但 schema.rb 文件的结果部分看起来不同:

create_table "agents", id: :integer, force: :cascade do |t|
  t.boolean  "status"
  t.string   "stripeId"
  t.integer  "UserID"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
end

如您所见,添加了“id: :integer”,但我没有发现任何原因。我试图将其更改为 :serial,转储我的数据库,重新加载模式(在所有类似的 Stack Overflow 问题中找到的建议)但没有任何帮助。过去,我曾经建立一个新模型,但那不是一个可扩展的解决方案。任何建议将不胜感激。

我还注意到错误只发生在本地,而不会发生在生产环境中(我使用 Heroku)。

如果需要,比较模型:

文章模型:

class Article < ApplicationRecord
  extend FriendlyId
  friendly_id :short_title, use: :slugged
end

代理模型:

class Agent < ApplicationRecord
end

我使用:

ruby 2.4.2p198(2017-09-14 修订版 59899)

rails 5.0.6

psql(9.6.1,服务器 9.6.6)

更新: 为了阐明我在寻找什么——我想保留自动生成的 ID,只是为了防止非空违规错误

最佳答案

只需将参数 id: false 添加到您的 create_table 调用中。另外,请注意括号。

查看 API Dock reference当你有机会的时候。

class CreateAgents < ActiveRecord::Migration[5.0]
  def change
    create_table(:agents, id: false) do |t|
      t.boolean :status
      t.string :stripeId
      t.integer :UserID

      t.timestamps
    end
  end
end

这是一个挑剔的添加,但您可能希望在您的命名约定中强制执行一些一致性。在列名称中使用“Id”或“ID”,但不要混用。它会让您的生活更轻松。

关于ruby-on-rails - 创建表时如何防止 rails 在 schema.rb 中插入 `id: :integer`?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48414313/

相关文章:

ruby-on-rails - 带有 Ruby on Rails 的 em-websocket gem

ruby-on-rails - 无法修改关联 'User#roles',因为源反射类 'Role' 通过 :has_many 关联到 'Profile'

ruby-on-rails - rails3,对使用 params[ :filename]. tempfile.path 与 params[ :filename][:tempfile]. path 感到困惑

ruby - 如何拆分大型 HAML 模板

postgresql - 从 DO 语句中的查询中获取结果

sql - 获取按列过滤的前几行

ruby-on-rails - ActiveAdmin 选择过滤器集合

jquery - .autocomplete 不是一个函数

java - 规范化 JSON 文件

postgresql - 使用手册页构建 PostgreSQL