【问题标题】:Getting an error message when I attempt to run seed script当我尝试运行种子脚本时收到错误消息
【发布时间】:2017-10-23 02:31:48
【问题描述】:
Rails 5.1

在我的seeds.rb 文件中,我有:

user = User.new(
    :email =>'random@myapp.com',
    :password =>'xK#986754',
    :password_confirmation =>'xK#986754',
    :first_name =>'John',
    :last_name =>'Smith',
    :role => 1
    :approved => true
)
user.skip_invitation
user.save

在我的 user.rb Molde 中,我有:

class User < ActiveRecord::Base

  enum role: [:user, :vip, :admin]
  after_initialize :set_default_role, :if => :new_record?


  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :invitable, :database_authenticatable, :registerable,
        :recoverable, :rememberable, :trackable, :validatable

  attr_accessor :email, :password, :first_name, :last_name, :role, :approved

  validates :email, uniqueness: true, presence: true
  validates :first_name, presence: true
  validates :last_name, presence: true
  validates :role, presence: true

  def set_default_role
    self.role ||= :user
  end
end

在我的迁移文件中,我有:

class DeviseCreateUsers < ActiveRecord::Migration[5.1]
  def change
    create_table :users do |t|

      t.string :first_name, null: false
      t.string :last_name, null: false
      t.integer :role, null: false
      t.string :email, null: false

      ## Approved
      t.boolean :approved, :default => 0, :null => false

当我尝试运行种子文件时,我收到以下错误消息:

ActiveRecord::NotNullViolation: Mysql2::Error: Field 'first_name' doesn't have a default value: INSERT INTO `users` (`approved`, `created_at`, `updated_at`) VALUES (1, '2017-10-23 02:23:36', '2017-10-23 02:23:36')

我显然在使用设计 gem

有什么想法吗?

【问题讨论】:

  • 提示:attr_accessor 在那些字段上做什么?这将阻止对底层数据库属性的访问。

标签: ruby-on-rails devise devise-invitable


【解决方案1】:

删除您的 attr_accessor 行。 attr_accessor 用于声明在类中包装实例变量的简单 getter/setter 方法,它不能与 Rails 模型一起用于要保存到数据库的属性。这实际上意味着所有 attr_accessor 属性仅存在于内存中,您的模型永远不会尝试将它们写入数据库,因此您的错误消息和插入查询中的所有缺失值。

【讨论】:

  • 删除 attr_accessor 行解决了问题。我误解了 attr_accessor 的工作原理。谢谢你的解释。
【解决方案2】:

您尚未提供名字值,并且您已告诉数据库不允许 null 但未提供默认值。

那么为什么你认为你已经提供了一个值,而实际上你并没有呢?你最后一次运行rails测试是什么时候?哪个会从一开始就掌握这个权利?

您的模型具有 attr_accessor 的名称,但您没有在任何地方从 attr_accessor 设置基础名称字段,因此要么摆脱 attr_accessor,要么在 before_save 中从名称 attr_accessor 设置名称字段

你真正想做的是删除你所有的 attr_accessor 另外,您为什么要混合编码样式?这是一种不好的做法,因为在维护方面它可能会让你身后的人感到困惑 在你的迁移中

t.boolean :approved, :default => 0, :null => false

应该是

t.boolean :approved, default: 0, null: false

使其符合 Rails 5 编码风格

【讨论】:

  • 我提供了一个名字,我误解的是 attr_accessor 的工作原理。
  • @EastsideDeveloper 不,你不认为你有。如果你有,那么代码就可以工作,因此“那么为什么你认为你提供了一个值,而实际上你没有提供?”这不仅仅是关于 attr_accessors ,而是关于您没有在自动生成的测试套件中更早地发现这个错误的事实,并表明需要更多的知识。如果您继续混合编码风格而不进行测试,您将走向失败
猜你喜欢
  • 1970-01-01
  • 2021-10-13
  • 1970-01-01
  • 1970-01-01
  • 2023-02-07
  • 2023-02-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多