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

发布于 2025-01-12 21:39:19 字数 2065 浏览 4 评论 0原文

我有一个为 Vue 前端提供数据的 Rails Api。我有两个主要模型,Contacts 和 Outlets,通过连接表 ContactOutlets 具有多对多关系。我试图弄清楚如何在联系人控制器中添加与插座的关联。

我认识到,我可以单独调用 ContactOutlet 创建操作,但如果 R​​ails 可以在后端处理这个问题,这似乎很浪费。我希望 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

ContactOutlet:

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

I have a Rails Api that feeds a Vue front end. I have two main models, Contacts and Outlets, with a many to many relationship via a join table ContactOutlets. I am trying to figure out how in the Contacts controller to add an association to an outlet.

I recognize, I could call the ContactOutlet create action separately, but it seems wasteful if Rails can handle this on the back end. I want vue to call contact#update once.

Contact Model:

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

Outlet Model:

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

  validates_uniqueness_of :website
end

ContactOutlet:

class ContactOutlet < ApplicationRecord
  belongs_to :contact
  belongs_to :outlet

  validates_uniqueness_of :contact_id, :scope => :outlet_id
end

Contacts Controller:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

不可一世的女人 2025-01-19 21:39:19

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

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

Solved this. In case anyone else is looking the models above are fine. made some adjustments to the contact_params to allow access to the outlets array. Then fixed the update action. Full controller code below:

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文