我在我的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
问题不在于tap
方法。 find_or_create
电话,字面意思,violates not-null constraint
。在tap
中,您正在使用现有对象,该对象无法使用您在find_or_create_by
中指定的参数写入数据库。随之而来的是create
和update
,而不仅仅是create
。
还有另一种方法可以像tap一样工作,但是在块中你可以在将对象写入数据库之前使用它:
PaymentMode.where(name: "Cash").first_or_create do |pm|
pm.instrument = false
pm.bank_account_allocation = false
end
至于我...我只是用find_or_initialize_by
和save
代替。