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
我有一个 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