2017-03-07 18 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