A have a Contact model with email uniqueness that can be soft deleted.
I want that when someone tries to create a contact with an e-mail taken by some soft_deleted contact, this new instance becomes the soft deleted record.
An example to make it clear
contact = Contact.new(email: 'sameemail@gmail.com')
contact.save # this got id = 1
contact.soft_destroy
# I expect contact2 to have id 1
contact2 = Contact.new(email: 'sameemail@gmail.com')
contact2.save
# I was able to do it with create
PS: I'm actually creating contacts as nested_attributes, so if I could do this spooky save as part of this, it would be great.
Event has_many Invites has_one Contact
The closest I got was this:
class Event < ApplicationRecord
accepts_nested_attributes_for :invites
before_save :restore_contacts
def restore_contacts
invites.each do |invite|
restorable_contact = Contact.find_by_email invite.contact.email
invite.contact = restorable_contact if restorable_contact
end
end
end
But it raises the validation error on the contact before this method is run :(
As you say, to solve the first part you have to do (maybe not the best choice, but I'm trying to explain the logic):
In your Contact
model
# app/models/contact.rb
class Contact < ApplicationRecord
validates :email, uniqueness: true
...
def restore
self.update_attribute deleted_by_user_at, nil
# other actions ...
end
...
end
Then, you can do the following:
contact = Contact.find_or_initialize_by email: "some@email.com"
if contact.persisted?
# email exists as Contact on DB
# it needs some extra validation
if contact.deleted_by_user_at.nil?
# email is already in use
else
# contact was soft deleted
contact.restore
end
else
# email is free to use
contact.save
end
If you really need use nested_attributes
you would have to change/add code, but logic will be the same
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.