外键未按预期工作

时间:2017-01-17 17:27:00

标签: ruby-on-rails postgresql ruby-on-rails-4

我知道它不是“The Rails Way”,但我正在尝试添加外键以在db级别强制执行引用完整性。我想创建一个名为recipe_ingredients的新表,它将引用一个名为recipes的表和一个名为ingredients的表。这是我的迁移:

class CreateRecipeIngredients < ActiveRecord::Migration
  def change
    create_table :recipe_ingredients do |t|
      t.references :recipe, null: false
      t.references :ingredient, null: false

      t.timestamps null: false
    end
    add_foreign_key :recipe_ingredients, :recipes
    add_foreign_key :recipe_ingredients, :ingredients
  end
end

迁移成功并生成以下内容:

                                                          Table "public.recipe_ingredients"
    Column     |            Type             |                            Modifiers                            | Storage  | Stats target | Description
---------------+-----------------------------+-----------------------------------------------------------------+----------+--------------+-------------
 id            | integer                     | not null default nextval('recipe_ingredients_id_seq'::regclass) | plain    |              |
 recipe_id     | integer                     |                                                                 | plain    |              |
 ingredient_id | integer                     |                                                                 | plain    |              |
 measurement   | character varying           | not null                                                        | extended |              |
 created_at    | timestamp without time zone | not null                                                        | plain    |              |
 updated_at    | timestamp without time zone | not null                                                        | plain    |              |
Indexes:
    "recipe_ingredients_pkey" PRIMARY KEY, btree (id)
Foreign-key constraints:
    "fk_rails_176a228c1e" FOREIGN KEY (recipe_id) REFERENCES recipes(id)
    "fk_rails_209d9afca6" FOREIGN KEY (ingredient_id) REFERENCES ingredients(id)

问题在于,当我尝试使用无效的recipe_id和/或ingredient_id创建新的recipe_ingredient时,它仍然认为它有效。如何让db在这些字段上强制实施参照完整性?我正在使用postgresql db。

2 个答案:

答案 0 :(得分:1)

调用valid?仅运行模型上的验证,直到您尝试将其实际插入到参考完整性检查所在的db中。

Rails 5中,模型中belongs_to会自动要求父项存在。

class Child < ApplicationRecord
  belongs_to :parent
end

您可以选择退出

belongs_to :parent, required: false

答案 1 :(得分:0)

我不一定会说这不是“Rails方式”。我喜欢考虑使用FK和模型验证,比如穿着腰带和吊带。那些时候你真的不想让你的裤子掉下来。