ActiveRecord :: StatementInvalid:SQLite3 :: ConstraintException:NOT NULL约束失败

时间:2015-11-30 06:02:02

标签: ruby-on-rails-4 activerecord

我按照以下步骤创建了一个简单的rails项目:

  1. rails new。
  2. rails g scaffold Post
  3. rails g scaffold Puzzle
  4. rails g model PostComment post_id:integer
  5. rake db:migrate
  6. rails g model PuzzleSave puzzle_id:integer
  7. rake db:migrate
  8. 在第5步之后,rake测试成功。 在步骤7之后,所有rake测试都失败并出现相同的错误:

      

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

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

    环境:

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

3 个答案:

答案 0 :(得分: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。

     

如果您设置了特定值,则他们将被单独留下。

PS。我查了一下,它也发生在PG数据库

答案 1 :(得分:1)

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表格中。

答案 2 :(得分:0)

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

  

问题很可能源于Rails无法复制/单一化模型名称Cave的事实:

     

IRB(主):003:0&GT; &#34;洞穴&#34; .pluralize

     

=&GT; &#34;洞穴&#34;

     

IRB(主):004:0&GT; &#34;洞穴&#34; .pluralize.singularize

     

=&GT; &#34;咖啡&#34;

     

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

     

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

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