【发布时间】:2019-09-08 15:13:15
【问题描述】:
我在我的 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 的原因它正在工作很好,但是在我的 PaymentMode 中添加了 null: false 约束(请参阅架构)后,我收到了这个错误:-
PG::NotNullViolation: ERROR: null value in column "instrument" violates not-null constraint
我可以解决这个错误吗?如果没有,有没有办法可以将数据放入我的 seed.rb 中,这样如果有人更新了种子,它应该更新相应的 ActiveRecord 对象?
附:我不想像这样 PaymentMode.find_or_create_by(name: "Cash", instrument: false).tap 将受约束的列保留在 find_or_create_by 参数中,因为如果有人将 instrument: false 更新为 instrument: true ,它会创建另一个对象
【问题讨论】:
-
我相信当您运行
rails db:migrate时会发生错误,对吗?如果是这种情况,那仅仅是因为您已经有一些PaymentMode记录,因此在不指定默认值的情况下创建列将意味着为其分配nil值,这显然是您在迁移中指定的不具有的值。 -
运行 rake db:seed 时出现错误,请再次阅读问题
-
哦,我明白你的意思了。我认为
#find_or_create_by不可能。可能最简单的方法是将其分解为多种方法。 -
也许你可以使用create_with
PaymentMode.create_with(instrument: false).find_or_create_by(name: "Cash")
标签: ruby-on-rails ruby activerecord ruby-on-rails-5 seeding