2017-03-07 37 views
0

SQLite3不允许将现有表的列转换为外键,但它确实允许在创建新表时但是当我打开.sqlite3文件时,此代码似乎没有创建带有外键的表?如何使用ActiveRecord在SQLite3中强制外键?

​​

当我在DB浏览器的SQLite点击“产品”,我希望它在架构,显示如下旁边的“产品”:

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) 
); 

相反,该模式具有以下未来到“产品”:

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文件以在产品和类别之间包含外键之后,products_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,为什么输出会失败并且是真的?

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

回答

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"); 
+0

怎样才能使 Somemodel.connection.foreign_key_exists?(:表A,:表B) 回是真的吗? – user2319683

+0

因此,ActiveRecord **在创建表迁移运行之后隐式地拥有外键,但不会将它们存储在任何使用的dbms上? 如果是这样,可以foreign_key_exists?永远回报真实? – user2319683