如何使用Ruby tap方法预填种子数据

问题描述 投票:0回答:1

我在我的seed.rb中使用Ruby的tap方法,如下所示: -

 PaymentMode.find_or_create_by(name: "Cash").tap do |pm|
  pm.instrument = false
  pm.bank_account_allocation = false
  pm.save!
 end

在schema.rb中,PaymentMode模型如下所示: -

  create_table "payment_modes", force: :cascade do |t|
    t.string "name"
    t.boolean "instrument", null: false
    t.boolean "bank_account_allocation"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["name"], name: "index_payment_modes_on_name", unique: true
  end

我希望如果有人更新种子文件(例如有人可以更新pm.bank_account_allocation = true)然后运行rake db:seed,相应的payment_mode的数据应该更新,这就是为什么我使用find_or_create_by它工作正常但我添加了null之后:我的PaymentMode中的错误约束(请参阅架构),我收到此错误: -

PG::NotNullViolation: ERROR:  null value in column "instrument" violates not-null constraint

我可以解决此错误吗?如果没有,有没有办法可以将数据放入我的seed.rb中,这样如果有人更新种子,它应该更新相应的ActiveRecord对象?

附:我不想将受限列保留在find_or_create_by params中,就像这个PaymentMode.find_or_create_by(name: "Cash", instrument: false).tap一样,因为如果有人更新仪器它会创建另一个对象:false to instrument:true

ruby-on-rails ruby activerecord ruby-on-rails-5 seeding
1个回答
3
投票

问题不在于tap方法。 find_or_create电话,字面意思,violates not-null constraint。在tap中,您正在使用现有对象,该对象无法使用您在find_or_create_by中指定的参数写入数据库。随之而来的是createupdate,而不仅仅是create

还有另一种方法可以像tap一样工作,但是在块中你可以在将对象写入数据库之前使用它:

PaymentMode.where(name: "Cash").first_or_create do |pm|
  pm.instrument = false
  pm.bank_account_allocation = false
end

至于我...我只是用find_or_initialize_bysave代替。

© www.soinside.com 2019 - 2024. All rights reserved.