【问题标题】:ActiveRecord::StatementInvalid: SQLite3::ConstraintException: NOT NULL constraint failedActiveRecord::StatementInvalid: SQLite3::ConstraintException: NOT NULL 约束失败
【发布时间】:2015-11-30 06:02:02
【问题描述】:

我通过以下步骤创建了一个简单的 Rails 项目:

  1. 导轨新。
  2. rails g 脚手架柱
  3. rails g 脚手架拼图
  4. rails g 模型 PostComment post_id:integer
  5. rake db:迁移
  6. rails g model PuzzleSave puzzle_id:integer
  7. rake db:迁移

在第 5 步之后,rake 测试成功。 在第 7 步之后,所有 rake 测试都失败并出现相同的错误:

ActiveRecord::StatementInvalid: SQLite3::ConstraintException: NOT NULL 约束失败:puzzle_saves.created_at: INSERT INTO "puzzle_saves" ("puzzle_id") 值 (1)

这个奇怪的错误是怎么发生的? created_at 字段不是自动生成的吗?而且我看不出在第 4 步和第 6 步中创建的模型之间有任何差异。

环境:

  • ruby 2.0.0p353(2013-11-22 修订版 43784)[i386-linux]
  • Rails 4.2.4

【问题讨论】:

    标签: ruby-on-rails-4 activerecord


    【解决方案1】:

    尝试将 created_at 时间戳添加到puzzle_saves.yml

    # puzzle_saves.yml
    
    one:
      puzzle_id: 1
      created_at: <%= Time.now %>
    
    two:
      puzzle_id: 2
      created_at: <%= Time.now %>
    

    这应该可以修复这些错误,但我不确定为什么需要这样做,因为该文档声称它应该自动完成 http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html

    自动填充的时间戳列

    如果您的表/模型指定了任何 Active Record 的标准时间戳 列(created_at、created_on、updated_at、updated_on)、 它们将自动设置为 Time.now。

    如果您设置了特定值,它们将被单独放置。

    附言。我查了一下,PG数据库也发生了这种情况

    【讨论】:

    • 谢谢。我从 github 得到了答案。 (见下面我的回答)。这个问题在 Rails 中,所以所有数据库都会发生。
    • 谢谢,@Marcin,你明白了!我有一个类似的问题,这完全是关于编辑固定装置(完全忘记了)以符合我的数据库约束。
    【解决方案2】:

    Marcin Kornek 解决方案是可靠的后备方案,但如果您有 STI 模型,为了自动设置时间戳,需要嵌套固定装置。

    module Dog
      class Base < ApplicationRecord
        self.table_name="dogs"
        belongs_to :owner
      end 
    
      class Baskerville < Dog::Base
      end
    
    end
    

    您的灯具必须设置为:

    fixtures/dog/baskervilles.yml 
    

    并且设置了正确的 STI 继承值, 正确加载(包括时间戳和命名夹具关联)

    little_b:
      type: "Dog::Baskerville"
      name: "Litte beast"
      owner: lord_baskerville
    

    所有的灯具都会被加载到dogs 表中。

    【讨论】:

      【解决方案3】:

      得到github/rails 的回复(模型洞穴也有类似问题)

      问题很可能源于 Rails 无法复数/单数模型名称 Cave:

      irb(main):003:0> "cave".pluralize

      => “洞穴”

      irb(main):004:0> “洞穴”.pluralize.singularize

      =>“咖啡馆”

      这使得 Active Record Fixtures 无法检测到生成的caves.yml 的模型,因此没有设置 created_at。

      如果您想使用 Rails 无法开箱即用的复数模型,请查看生成的 config/initializers/inflections.rb。在生成脚手架之前添加以下行应该可以解决问题:

      ActiveSupport::Inflector.inflections(:en) do |inflect|
          inflect.irregular 'cave', 'caves'
      end
      

      【讨论】:

        猜你喜欢
        • 2013-01-20
        • 1970-01-01
        • 2019-12-25
        • 1970-01-01
        • 2022-08-10
        • 2018-06-10
        • 2021-08-07
        • 2015-12-31
        • 2021-07-02
        相关资源
        最近更新 更多