如何使用ActiveRecord强制SQLite3中的外键?

时间:2017-03-07 21:48:43

标签: ruby-on-rails ruby activerecord sqlite

SQLite3不允许将现有表的列设置为外键,但在创建新表时允许这样做,但是当我打开.sqlite3文件时,此代码似乎不会创建带有外键的表?

class CreateProducts < ActiveRecord::Migration[5.0]
  def change
    create_table :products do |t|
      t.string :name
      t.text :description
      t.float :cost
      t.references :category, foreign_key: true

      t.timestamps
    end
  end
end

当我点击&#34;产品&#34;在SQL Browser的DB Browser中,我希望它能在&#34;产品&#34;旁边显示以下内容。在架构中:

CREATE TABLE `products` (
    `id`    INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
    `name`  varchar,
    `description`   text,
    `cost`  float,
    `category_id`   integer,
    `created_at`    datetime NOT NULL,
    `updated_at`    datetime NOT NULL,
    FOREIGN KEY(`category_id`) REFERENCES categories ( id )
);

相反,该架构在&#34; products&#34;:

旁边有以下内容
CREATE TABLE `products` (
    `id`    INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
    `name`  varchar,
    `description`   text,
    `cost`  float,
    `category_id`   integer,
    `created_at`    datetime NOT NULL,
    `updated_at`    datetime NOT NULL,
);

那么如何让迁移强制.sqlite3文件有一个外键?

即使我手动编辑.sqlite3文件以在产品和类别之间包含外键,product_controller.rb中的代码中的以下内容也会返回false,false和true。

@current_connection = Product.connection
puts @current_connection.foreign_key_exists?(:categories, :products)
puts @current_connection.foreign_key_exists?(:products, :categories)
puts @current_connection.index_exists?(:products, :category_id)

如果正在使用.sqlite3,为什么输出会变为falses而一个是真的?

此外,在运行创建产品的迁移时,PostgreSQL表是否会有外键,还是会出现同样的问题?

1 个答案:

答案 0 :(得分:0)

试试这个

class CreateProducts < ActiveRecord::Migration[5.0]
  def change
    create_table :products do |t|
      t.string :name
      t.text :description
      t.float :cost
      t.references :category, foreign_key: true
      add_foreign_key :products, :categories, foreign_key: true

      t.timestamps
    end
  end
end

结果:

CREATE TABLE "products" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar, "description" text, "cost" float, "category_id" integer, "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL);
CREATE INDEX "index_products_on_category_id" ON "products" ("category_id");