Rails API 控制器更新操作 -- 如何添加多对多

Rails API Controller Update Action -- How to add many-to-many

我有一个 Rails Api 提供 Vue 前端。我有两个主要模型,Contacts 和 Outlets,它们通过 join table ContactOutlets 建立多对多关系。我想弄清楚如何在联系人控制器中将关联添加到出口。

我知道,我可以单独调用 ContactOutlet create 操作,但如果 Rails 可以在后端处理它似乎很浪费。我希望 vue 调用 contact#update 一次。

联系方式:

class Contact < ApplicationRecord
  has_many :contact_outlets
  has_many :outlets, through: :contact_outlets
  has_many :calls

  validates_uniqueness_of :email
  validates_uniqueness_of :name

end

插座型号:

class Outlet < ApplicationRecord
  has_many :contact_outlets
  has_many :contacts, through: :contact_outlets
  has_many :calls

  validates_uniqueness_of :website
end

联系方式:

class ContactOutlet < ApplicationRecord
  belongs_to :contact
  belongs_to :outlet

  validates_uniqueness_of :contact_id, :scope => :outlet_id
end

联系人控制器:

class ContactsController < ApplicationController
  before_action :set_contact, only: %i[ show update destroy ]

  # GET /contacts
  def index
    @contacts = Contact.all

    render json: @contacts, include: :outlets
  end

  # GET /contacts/1
  def show
    render json: @contact, include: :outlets
  end

  # POST /contacts
  def create
    @contact = Contact.new(contact_params)

    if @contact.save
      render json: @contact, status: :created, location: @contact
    else
      render json: @contact.errors, status: :unprocessable_entity
    end
  end

  # PATCH/PUT /contacts/1
  def update
    if @contact.update(contact_params)
      render json: @contact, include: :outlets
    else
      render json: @contact.errors, status: :unprocessable_entity
    end
  end

  # DELETE /contacts/1
  def destroy
    @contact.destroy
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_contact
      @contact = Contact.find(params[:id])
    end

    # Only allow a list of trusted parameters through.
    def contact_params
      params.require(:contact).permit(:name, :email, :bio, :image_url)
    end
end

解决了这个问题。如果其他人正在看上面的模型就可以了。对 contact_params 进行了一些调整以允许访问 outlets 数组。然后修复了更新操作。完整的控制器代码如下:

class ContactsController < ApplicationController
  before_action :set_contact, only: %i[ show update destroy ]

  # GET /contacts
  def index
    @contacts = Contact.all

    render json: @contacts, include: :outlets
  end

  # GET /contacts/1
  def show
    render json: @contact, include: :outlets
  end

  # POST /contacts
  def create
    @contact = Contact.new(contact_params)

    if @contact.save
      render json: @contact, status: :created, location: @contact
    else
      render json: @contact.errors, status: :unprocessable_entity
    end
  end

  # PATCH/PUT /contacts/1
  def update
    if @contact.outlets
      @contact.outlets.delete_all
    end
    if params[:outlets]
      contactOutlets = params[:outlets]
      contactOutlets.each do |outlet|
        @contact.outlets << Outlet.find(outlet[:key])
      end
    end
    if @contact.update(contact_params)
      render json: @contact, include: :outlets
    else
      render json: @contact.errors, status: :unprocessable_entity
    end
  end

  # DELETE /contacts/1
  def destroy
    @contact.destroy
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_contact
      @contact = Contact.find(params[:id])
    end

    # Only allow a list of trusted parameters through.
    def contact_params
      params.require(:contact).permit(:name, :email, :bio, :image_url, outlet_ids:[])
    end
end