Reputation: 4963
When I try to create a new Devise user, I get the error:
ActiveRecord::RecordNotUnique: TinyTds::Error: Cannot insert duplicate key row in object 'dbo.admin_users' with unique index 'index_admin_users_on_reset_password_token'. The duplicate key value is (NULL)
This is because the index 'index_admin_users_on_reset_password_token' requires unique values in the reset_password_token field, and every User that gets created is submitted with a nil
value in that field, which means every record past the first will not be unique.
When I try to manually submit a value in that field it is automatically ommitted.
user = AdminUser.new(email: "[email protected]", password: "integracore", reset_password_token:"french fries", reset_password_sent_at: Time.now)
#<AdminUser:0x000000075303e8
# id: nil,
# email: "[email protected]",
# encrypted_password: "$2a$10$cm9AmPuwEey4hDFMUPMMkeD3bLPozT47VLdmg9kDlDRKBXh93Hn0C",
# reset_password_token: "french fries",
# reset_password_sent_at: Thu, 03 Sep 2015 19:42:25 UTC +00:00,
# remember_created_at: nil,
# sign_in_count: 0,
# current_sign_in_at: nil,
# last_sign_in_at: nil,
# current_sign_in_ip: nil,
# last_sign_in_ip: nil,
# created_at: nil,
# updated_at: nil>
user.save
ActiveRecord::RecordNotUnique: TinyTds::Error: Cannot insert duplicate key row in object 'dbo.admin_users' with unique index 'index_admin_users_on_reset_password_token'. The duplicate key value is ().: EXEC sp_executesql N'INSERT INTO [admin_users] ([email], [encrypted_password], [created_at], [updated_at]) OUTPUT INSERTED.[id] VALUES (@0, @1, @2, @3)', N'@0 nvarchar(4000), @1 nvarchar(4000), @2 datetime, @3 datetime', @0 = N'[email protected]', @1 = N'$2a$10$cm9AmPuwEey4hDFMUPMMkeD3bLPozT47VLdmg9kDlDRKBXh93Hn0C', @2 = '09-03-2015 19:45:11.555', @3 = '09-03-2015 19:45:11.555'
How can I get past this error and create a new user?
Upvotes: 0
Views: 333
Reputation: 4963
So I added this workaround for the time being. I basically just update all NULL records before and after creating a new user. I would prefer to do it the 'Devise way' so if someone posts that I will choose that as the answer, but this will work for now:
class AdminUser < ActiveRecord::Base
devise :database_authenticatable,
:recoverable, :rememberable, :trackable, :validatable
# Create new user #############################################################
def self.add_user (email:,password:"password")
clean_empty_reset_tokens
user = self.create(email:email,password:password)
user.set_reset_token
return user
end
def set_reset_token token = self.class.generate_token
update(reset_password_token: token)
return token
end
def self.clean_empty_reset_tokens
where(reset_password_token:nil).each do |user|
user.update(reset_password_token:generate_token)
end
end
def self.generate_token
raw_token, hashed_token = Devise.token_generator.generate(self, :reset_password_token)
return hashed_token
end
# End create new user #########################################################
end
Upvotes: 0