【问题标题】:Foreign key not working as expected外键未按预期工作
【发布时间】:2017-01-17 17:26:59
【问题描述】:

我知道它不是“Rails 方式”,但我正在尝试添加外键以在数据库级别强制执行参照完整性。我想创建一个名为 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 和/或成分 ID 创建新的 recipe_ingredient 时,它仍然认为它有效。如何让数据库在这些字段上强制执行参照完整性?我正在使用 postgresql 数据库。

【问题讨论】:

  • 那些 FK 应该强制执行参照完整性。谁认为这些无效行是有效的?为什么recipe_idingredient_id 列也不是not null
  • 有效是什么意思?如果模型说它是有效的,那是因为那里没有验证,这并不意味着你可以将它插入到数据库中。
  • 哇,我觉得自己很愚蠢。我使用的是.valid?,它当然只在模型中运行验证。当我尝试保存到数据库时它可以正常工作。谢谢@Iceman :-)
  • 没有问题,我做了一个答案,所以这个问题可以关闭:)

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


【解决方案1】:

调用valid? 仅在模型上运行验证,直到您尝试将其实际插入到数据库中,引用完整性检查才会启动。

Rails 5 中,在您的模型中拥有belongs_to 会自动要求父级存在。

class Child < ApplicationRecord
  belongs_to :parent
end

你可以选择退出这个

belongs_to :parent, required: false

【讨论】:

    【解决方案2】:

    我不一定会说这不是“Rails 方式”。我喜欢考虑使用 FK 和模型验证,例如佩戴腰带和吊带。在那些时候,你真的不希望你的裤子掉下来。

    【讨论】:

      猜你喜欢
      • 2020-01-26
      • 2021-12-03
      • 1970-01-01
      • 2013-08-06
      • 2012-08-05
      • 2015-06-17
      • 2017-07-13
      • 2016-02-24
      • 2013-07-19
      相关资源
      最近更新 更多