我正在为大迁移编写脚本并且遇到了一个重大问题。
# Import users
user_data.each do |data|
u = User.new
u.id = data.id
u.email = data.email
# more user attributes set...
u.save!
end
# required to prevent Postgres from trying to use now taken user ids
ActiveRecord::Base.connection.execute "ALTER SEQUENCE users_id_seq RESTART WITH #{User.last.id+1};"
所以首先我们从数据源中读取用户数据,并手动设置它的 id。我们需要保留 id,因为我们也在迁移相关数据。
然后稍后,我们需要根据关联对象的数据有条件地创建更多用户。
# Create a user for this email if no user with this email exists.
if data.email
user = User.find_by_email(data.email)
if user
o.user = user
else
o.user = User.create!(
first_name: 'Unknown',
last_name: 'Unknown',
email: data.email,
password: generate_temp_password
)
end
end
这失败User.create!
了:
Validation failed: Email has already been taken (ActiveRecord::RecordInvalid)
我已经对此进行了一些调试,并且可以在引发此错误之前看到它User.where(email: data.email).first
。nil
我怀疑这与设置超出当前自动增量值的 ID 有关,以某种方式导致新记录在我的查询中不可见,但对 Postgres 自己的验证可见。
那么具有特定电子邮件的用户如何不存在,但仍会触发数据库验证错误呢?