简体   繁体   English

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

[英]How to find or update a record though a nested attributes form (Rails 6)

tldr: How do I find and update or create a record through a nested association? tldr:如何通过嵌套关联查找和更新创建记录?

I have a Registrations model that belongs to a Lead model.我有一个属于潜在客户 model 的注册 model。 Leads are created via nested attributes when the user submits the registration form.当用户提交注册表单时,潜在客户是通过嵌套属性创建的。 This works fine, but now I need to update the Registration so that it either creates a new lead, OR finds and updates the lead if a lead already exists with that email.这工作正常,但现在我需要更新注册,以便它创建新的潜在客户,或者如果 email 的潜在客户已经存在,则查找并更新潜在客户。

registration.rb:注册.rb:

class Registration < ApplicationRecord
  belongs_to :showing
  belongs_to :lead

  accepts_nested_attributes_for :lead
  validates_associated :lead

end

lead.rb铅.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注册控制器.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, :email, :phone, :agent, :mortgage, :source])
    end

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

maybe this one will help也许这个会有所帮助

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

or this或这个

https://dev.to/katkelly/why-yes-i-ll-accept-those-nested-attributes-18f7 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

For others who are working on similar features, here's how I solved it (below).对于正在研究类似功能的其他人,这是我解决它的方法(如下)。 Ultimately, I chose to go with a callback and not override the autosave method.最终,我选择了带有回调的 go 并且不覆盖自动保存方法。 When overriding the autosave method, I was running into problems setting the nested object id on the parent object in the join table.覆盖自动保存方法时,我在连接表的父 object 上设置嵌套 object id 时遇到问题。 So, I went with the following callback process:因此,我采用了以下回调过程:

  1. check if a lead exists by that email检查该 email 是否存在潜在客户
  2. if one exists, update the existing lead with the new lead attributes如果存在,则使用新的潜在客户属性更新现有潜在客户
  3. set the new lead to the updated existing lead将新潜在客户设置为更新的现有潜在客户
  4. if lead doesn't exist, pass the new lead back to the controller for creation如果铅不存在,将新铅传回 controller 进行创建
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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM