【问题标题】:Rails4 migration- adding null: false to an add_reference method?Rails4迁移-将null:false添加到add_reference方法?
【发布时间】:2015-08-31 07:17:11
【问题描述】:

我刚刚开始学习 Rails,如果这个问题的答案相当明显,我很抱歉。

我在我的应用程序中添加了帖子和类别表的迁移,现在我正在使用以下行在我的帖子表中添加对类别的引用,默认值不为空:

add_reference :posts, :category, index: true, foreign_key: true, null: false

但是在运行迁移时出现以下错误:

SQLite3::SQLException: Cannot add a NOT NULL column with default value NULL: ALTER TABLE "posts" ADD "category_id" integer NOT NULL

我已经尝试通过 api 阅读,但无法弄清楚我做错了什么。

【问题讨论】:

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


【解决方案1】:

也许 sqlite3 不允许这样做, 试试

add_reference :posts, :category, index: true, foreign_key: true, null: false
change_column :posts, :category_id, :integer, null: false

【讨论】:

    【解决方案2】:

    经过进一步阅读,这似乎是 sqlite3 的一个错误。显然,在对现有表进行更改时,您不能像上面那样向引用添加非空值(这在 MYSQL 中有效)。但是,您可以在从头开始创建表时执行此操作。通过将上面的行添加到我的 create_table 迁移中,设法让它工作。

    【讨论】:

    • sqlite 是正确的,它应该是这样工作的。还有其他关系数据库以这种方式运行。
    • 我不明白为什么 sqlite 在这种情况下是正确的。 “必须具有值”的外键是跨大规模数据库引擎支持的正常要求。但是我没有找到像 L457 建议的那样在 create_table 期间添加引用的好方法。
    【解决方案3】:

    注意:使用引用时,there is no need to specify index: true

    【讨论】:

      【解决方案4】:

      该消息基本上是说,如果不为其定义默认值,则无法创建“非空”列。

      我认为您应该删除 null: false 选项。

      为防止 NULL 值出现在 POSTS 表中,添加

      validates :category, presence: true

      到您的Post 模型。

      另见请查看此帖子 https://robots.thoughtbot.com/referential-integrity-with-foreign-keys,以更好地了解 Rails 中的外键。

      【讨论】:

      • 感谢您的回复,验证在我的模型上正常工作。我在一个教程中读到,在数据库级别添加验证以及请求偶尔会通过模型验证的最佳实践,特别是在流量很大的情况下,这就是我一直在尝试上述方法的原因。有没有更好的方法来向该列添加非空值,或者在这种情况下将验证留给模型是否可以?再次感谢
      • @Lin457 我添加了一个博客文章的链接,您可以在其中阅读有关保护外键的数据库部分的更多信息。
      • @Lin457 这不是 sqlite3 的错误。我不确定 MySQL,但其他几个数据库也有相同的行为。
      • 我认为在可能的情况下在数据库级别强制执行对表(和应用程序)至关重要的事情通常是一个好主意
      猜你喜欢
      • 1970-01-01
      • 2015-02-21
      • 2017-07-07
      • 2019-03-03
      • 2020-03-13
      • 2023-04-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-26
      相关资源
      最近更新 更多