我有两个模型想要根据需要手动关联或分离。
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 的方法是什么?
我的命令是定义这条路线:
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
最后,这取决于您以及您如何看待您的应用领域!