Rails在保存时替换ApplicationRecord实例

时间:2017-02-21 01:02:56

标签: ruby-on-rails activerecord

A有一个具有电子邮件唯一性的联系人模型,可以软删除。

我希望当有人尝试使用某个soft_deleted联系人发送的电子邮件创建联系人时,此新实例将成为软删除记录。

明确的例子

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:我实际上是以nested_attributes的形式创建联系人,所以如果我可以做这个幽灵般的保存,那就太好了。

活动has_many邀请has_one联系

我最接近的是:

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

但是在运行此方法之前,它会在联系人上引发验证错误:(

1 个答案:

答案 0 :(得分:0)

正如你所说,要解决你必须做的第一部分(也许不是最好的选择,但我试图解释逻辑):

Contact模型中

# 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

然后,您可以执行以下操作:

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

如果你真的需要使用nested_attributes,你必须更改/添加代码,但逻辑将是相同的