Rails 通过 JSON 调用创建/销毁现有模型的关联

问题描述 投票:0回答:1

我有两个模型想要根据需要手动关联或分离。

class Car < ApplicationRecord
  has_many :wheels, dependent: :nullify
end

class Wheel < ApplicationRecord
  belongs_to :car
end

假设我的数据库已经充满了

cars
wheels
。我不知道使用 JSON API 调用将
wheel
关联到
car
的正确方法是什么,或者在
wheel
已经填充了
car_id
时取消关联。

我应该创建一个嵌套路由,例如:

resources :cars do
  resources :wheels, only: [:add_to_car, :remove_from_car]
end

但是

add_to_car
remove_from_car
方法不会出现在路由列表中。

理想情况下,我想做一些类似

/cars/:id/add_wheel/:wheel_id
(或类似更RESTful友好的事情)

Rails 的方法是什么?

ruby-on-rails routes rails-api
1个回答
0
投票

我的命令是定义这条路线:

POST /cars/:id/add_wheel/:wheel_id for adding a wheel to a car.
DELETE /cars/:id/remove_wheel/:wheel_id for removing a wheel from a car.

你可以做这样的事情

# config/routes.rb
resources :cars do
  member do
    post 'add_wheel/:wheel_id', to: 'cars#add_wheel'
    delete 'remove_wheel/:wheel_id', to: 'cars#remove_wheel'
  end
end

那么你的控制器应该如下所示:

class CarsController < ApplicationController
  # POST /cars/:id/add_wheel/:wheel_id
  def add_wheel
    car = Car.find(params[:id])
    wheel = Wheel.find(params[:wheel_id])

    wheel.update(car: car)

    if wheel.save
      render json: wheel, status: :ok
    else
      render json: wheel.errors, status: :unprocessable_entity
    end
  end

  # DELETE /cars/:id/remove_wheel/:wheel_id
  def remove_wheel
    car = Car.find(params[:id])
    wheel = car.wheels.find(params[:wheel_id])

    wheel.update(car: nil)

    if wheel.save
      render json: { message: "Wheel removed from car" }, status: :ok
    else
      render json: wheel.errors, status: :unprocessable_entity
    end
  end
end

无论如何,还有另一种更RESTFUL的方法,因为如果你看到前面的答案,你会注意到方向盘上有一个表演,这不是很RESTful。但如果你的模型是这样的:

# app/models/car.rb
class Car < ApplicationRecord
  has_many :wheels, dependent: :nullify

  # Adds a wheel to the car
  def add_wheel(wheel_id)
    wheel = Wheel.find_by(id: wheel_id)
    wheels << wheel if wheel && wheel.car_id != self.id
  end

  # Removes a wheel from the car
  def remove_wheel(wheel_id)
    wheel = wheels.find_by(id: wheel_id)
    wheel.update(car_id: nil) if wheel
  end
end

然后在你的控制器中你可以这样写:

def add_wheel
  @car = Car.find(params[:id])
  
  if @car.add_wheel(params[:wheel_id])
     good
  else
     not good...
  end
end

另一件事是你可以考虑有类似的路线

# config/routes.rb
resources :wheels, only: [] do
  member do
    post 'add_to_car', to: 'wheels#add_to_car'
    delete 'remove_from_car', to: 'wheels#remove_from_car'
  end
end

控制器:

class WheelsController < ApplicationController
  # POST /wheels/:id/add_to_car
  def add_to_car
    wheel = Wheel.find(params[:id])
    car = Car.find(params[:car_id]) # Assuming `car_id` is passed as part of the request parameters

    wheel.car = car
    if wheel.save
      render json: wheel, status: :ok
    else
      render json: wheel.errors, status: :unprocessable_entity
    end
  end

  # DELETE /wheels/:id/remove_from_car
  def remove_from_car
    wheel = Wheel.find(params[:id])
    
    wheel.car = nil
    if wheel.save
      render json: { message: 'Car association removed successfully.' }, status: :ok
    else
      render json: wheel.errors, status: :unprocessable_entity
    end
  end
end

最后,这取决于您以及您如何看待您的应用领域!

© www.soinside.com 2019 - 2024. All rights reserved.