我试图用Rails将一个新记录保存到SQLite,但到目前为止还没有成功。
我有一个用于“sections”的表,其中有一列用于“sectioncode”,它被另一个名为“spaces”的表引用为“sectioncode_id”。
章节:
Section(id: integer, sectioncode: integer, name: string, description: text, created_at: datetime, updated_at: datetime)
空间:
Space(id: integer, spacecode: integer, name: string, description: text, sectioncode_id: integer, created_at: datetime, updated_at: datetime)
(其中sectioncode_id
引用节的sectioncode
列)
在第.rb节中:
has_many :spaces, foreign_key: :sectioncode_id, primary_key: :sectioncode, dependent: :destroy
在Space.rb中:
belongs_to :section, foreign_key: :sectioncode_id, primary_key: :sectioncode, required: true
在用于创建空间的移植文件中:
t.references :sectioncode, foreign_key: {to_table: :sections}
当我尝试将新记录保存到Spaces时,Rails显示SQLite3::ConstraintException: FOREIGN KEY constraint failed (ActiveRecord::InvalidForeignKey)
。
TL;DR:Rails报告了一个Invalid Foreign Key,但SQLite本身没有。
我试着看看是否可以通过SQLite控制台手动创建记录,并且我能够,没有任何错误。当我这样做时,Rails正确地处理了我执行的所有其他操作的关系。我使用了Rails与SQLite报告的相同命令。
Rails:
TRANSACTION (0.1ms) begin transaction
Space Exists? (0.2ms) SELECT 1 AS one FROM "spaces" WHERE "spaces"."spacecode" = ? AND "spaces"."sectioncode_id" = ? LIMIT ? [["spacecode", 1], ["sectioncode_id", 1], ["LIMIT", 1]]
Space Create (0.6ms) INSERT INTO "spaces" ("spacecode", "name", "description", "sectioncode_id", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["spacecode", 1], ["name", "S1"], ["description", "D1"], ["sectioncode_id", 1], ["created_at", "2023-04-02 00:16:19.836125"], ["updated_at", "2023-04-02 00:16:19.836125"]]
TRANSACTION (0.1ms) rollback transaction
/Users/user/.rvm/gems/ruby-3.0.0/gems/sqlite3-1.6.1-x86_64-darwin/lib/sqlite3/statement.rb:108:in `step': SQLite3::ConstraintException: FOREIGN KEY constraint failed (ActiveRecord::InvalidForeignKey)
/Users/user/.rvm/gems/ruby-3.0.0/gems/sqlite3-1.6.1-x86_64-darwin/lib/sqlite3/statement.rb:108:in `step': FOREIGN KEY constraint failed (SQLite3::ConstraintException)
但是,带有["sectioncode", 1]
的部分确实存在:
3.0.0 :013 > Section.find_by!(sectioncode: 1)
Section Load (0.1ms) SELECT "sections".* FROM "sections" WHERE "sections"."sectioncode" = ? LIMIT ? [["sectioncode", 1], ["LIMIT", 1]]
=>
#<Section:0x00007ff41089a010
id: 4,
sectioncode: 1,
name: "Sec1",
description: "Desc1",
created_at: Sun, 02 Apr 2023 00:16:12.260733000 UTC +00:00,
updated_at: Sun, 02 Apr 2023 00:16:12.260733000 UTC +00:00>
在SQLite上:
sqlite> INSERT INTO "spaces" ("spacecode", "name", "description", "sectioncode_id", "created_at", "updated_at") VALUES (1, "S1", "D1", 1, "2023-04-02 00:16:19.836125", "2023-04-02 00:16:19.836125");
sqlite>
这成功地保存了具有正确外键关系的记录。
为什么会发生这种情况?它到底在哪里失败了?
编辑:下面是我用来保存新空间的代码:
space = Space.new(spacecode: 1, name: "S1 (Seeded)", description: "D1", sectioncode_id: 1)
space.save
1条答案
按热度按时间wsewodh21#
这将在
spaces.sectioncode_id
上设置一个a约束,以引用sections.id
:因为
spaces.sectioncode_id
100
不匹配sections.id
1
。在sqlite中,您必须启用外键检查:
下面是如何修复它:
一个三个三个一个
spacecode
和sectioncode
看起来是不必要的,你在重复id
的角色。如果有什么不同的话,两者都应该被命名为code
:这样就简单多了: