我在我的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的数据,这就是为什么我使用{{1} }工作正常,但是我在我的PaymentMode中添加了null:false约束(请参阅架构)后,出现此错误:-
find_or_create_by
我可以解决此错误吗?如果没有,是否有办法将数据放入seed.rb,以便如果有人更新了种子,则应该更新各自的ActiveRecord对象?
P.S。我不想将受约束的列保留在像PG::NotNullViolation: ERROR: null value in column "instrument" violates not-null constraint
这样的find_or_create_by参数内,因为如果有人将Instrument:false更改为Instrument:true,它将创建另一个对象
答案 0 :(得分:3)
问题不在于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
。