如何通过嵌套的属性表单查找或更新记录Rails 6

问题描述

tldr:如何通过嵌套关联查找和更新创建记录?

我有一个属于 Lead 模型的注册模型。当用户提交注册表时,通过嵌套属性创建潜在客户。这工作正常,但现在我需要更新注册,以便它创建一个新的潜在客户,或者如果该电子邮件中已经存在潜在客户,则查找并更新潜在客户。

注册.rb:

class Registration < ApplicationRecord
  belongs_to :showing
  belongs_to :lead

  accepts_nested_attributes_for :lead
  validates_associated :lead

end

lead.rb

class Lead < ApplicationRecord
  belongs_to :account
  has_many :registrations,dependent: :destroy
  has_many :showings,through: :registrations
  validates :name,:email,:phone,presence: true

end

registrations_controller.rb

class RegistrationsController < ApplicationController
  before_action :set_account

  def index
    redirect_to new_showing_registration_path
  end

  def new
    @registration = @showing.registrations.build
    @lead = Lead.new
  end

  def create
    @showing = Showing.find(params[:showing_id])
    @registration = @showing.registrations.build(registration_params)
    if @registration.save
      redirect_to new_showing_registration_path,notice: 'Thank you for registering.'
    else
      render :new,status: :unprocessable_entity
    end
  end

  def show
    redirect_to new_showing_registration_path
  end

  def edit
    @showing = Showing.find(params[:showing_id])
    @registration = Registration.find(params[:id])
    @account_id = @showing.listing.account.id.to_i
  end

  def update
    @registration = Registration.find(params[:id])
    if @registration.update(registration_params)
      redirect_to new_showing_registration_path,notice: 'Thank you for registering.'
    else
      render :edit,status: :unprocessable_entity
    end
  end

  private
    def registration_params
      params.require(:registration).permit(lead_attributes: [:account_id,:id,:name,:agent,:mortgage,:source])
    end

    def set_account
      @showing = Showing.find(params[:showing_id])
      @account_id = @showing.listing.account.id.to_i
    end
end

解决方法

也许这个会有所帮助

https://stackoverflow.com/a/3580267/11544219

或者这个

https://dev.to/katkelly/why-yes-i-ll-accept-those-nested-attributes-18f7


class Registration < ApplicationRecord
  belongs_to :showing
  belongs_to :lead

  accepts_nested_attributes_for :lead
  validates_associated :lead

  def autosave_associated_records_for_lead
   existed_lead = Lead.find_by(registration: self)
   if existed_lead.present?
     existed_lead.update!(lead.attributes)
   else
     lead.save!
   end
  end

end
,

对于正在研究类似功能的其他人,这是我解决它的方法(如下)。最终,我选择使用回调而不是覆盖自动保存方法。在覆盖自动保存方法时,我在连接表中的父对象上设置嵌套对象 ID 时遇到了问题。所以,我采用了以下回调过程:

  1. 检查该电子邮件是否存在潜在客户
  2. 如果存在,则使用新的潜在客户属性更新现有潜在客户
  3. 将新潜在客户设置为更新后的现有潜在客户
  4. 如果线索不存在,则将新线索传回控制器进行创建
class Registration < ApplicationRecord
  belongs_to :showing
  belongs_to :lead
  accepts_nested_attributes_for :lead,:reject_if => :all_blank,allow_destroy: true
  before_validation :update_or_create_lead

  private

  def update_or_create_lead
    existing = Lead.find_by(email: self.lead.email)
    if existing
      existing.update(
        name: lead.name,phone: lead.phone,agent: lead.agent,mortgage: lead.mortgage,source: lead.source
    )
      self.lead = existing
    else
      self.lead
    end
  end

end