在我的Rails 4应用程序中,我有以下模型:
class Location < ActiveRecord::Base
has_many :location_parking_locations
has_many :parking_locations, through: :location_parking_locations
end
class LocationParkingLocation < ActiveRecord::Base
belongs_to :location
belongs_to :parking_location
end
class ParkingLocation < ActiveRecord::Base
has_many :location_parking_locations
has_many :locations, through: :location_parking_locations
end对路由/locations/1/parking_locations的调用返回位置= 1的停车位置集合。响应中的一些属性来自连接模型( location_parking_location)。例如,响应中的一个parking_locations可能如下所示:
{
id: 1
name: 'Test Parking Location'
description: 'Test description for the parking location'
upvote_count: 10, <- this field comes from the join model
downvote_count: 8, <- this field comes from the join model
}如果用户想要更新一个直接来自停车场的属性,例如名称,我觉得他们应该能够通过一个端点来更新这个属性,该端点将停车场作为一个主要资源,而不是将其作为特定位置的子资源引用。例如,它们应该能够从端点parking_location (而不是特定于特定位置)编辑或检索端点/parking_locations/1。
在这种情况下,不应该包括来自location_parking_location (如upvote_count )和downvote_count的字段。
是否有某种允许这种行为的设计模式?还是我应该换个角度考虑这个问题?例如,在检索端点locations/1/parking_locations时,我不应该返回parking_locations的集合,而是应该返回location_parking_locations的集合,该集合可以包括表示来自parking_location的属性的对象。在这种情况下,端点是否应该更改为locations/1/location_parking_locations?例如,响应中的一个对象可能如下所示:
{
id: 9
upvote_count: 10,
downvote_count: 8,
parking_location: {
id: 1
name: 'Test Parking Location'
description: 'Test description for the parking location'
}
}在这种情况下,怎么会有人增加一个新的停车位?它是否会通过发布到/parking_locations端点来完成呢?或者他们是否应该同时创建它并将其添加到某个位置,也许可以通过将其发布到/locations/1/parking_locations
在这种情况下,如果有人想要将一个已经存在的停车位置添加到某个位置,该怎么办?在这种情况下,也许他们应该把/locations/1/parking_locations/{parking_location_id}
发布于 2015-12-10 15:53:27
路线
您可以通过一些简单的路由和允许的控制器使您的ParkingLocation模型成为主资源和子资源。首先,路由-除了您已经将其作为Location的子资源的位置之外,您还需要在顶层声明它。
resources :locations do
resources :parking_locations
end
resources :parking_locations如果现在检查rake routes,您将看到两组连接到ParkingLocationsController的URL,一组位于/parking_locations,另一组嵌套在/locations/:location_id/parking_locations。
ParkingLocationsController
您的控制器将始终接收包含params[:id] ID的ParkingLocation。如果您访问嵌套路由,它还将接收包含params[:location_id] ID的Location。任何表单提交等都将包含params[:parking_location],其中包含create/update/etc的其余属性。一个简单的控制器可能如下所示:
class ParkingLocationsController
def index
if params[:location_id]
location = Location.find(params[:location_id])
@parking_locations = location.parking_locations
else
@parking_locations = ParkingLocation.all
end
end
def show
@parking_location = ParkingLocation.find(params[:id])
end
# ...
end注index的工作原理是相同的,而不管location_id参数来自何处:
/locations/1/parking_locations
/parking_locations?location_id=1添加位置
因为您的RESTful资源是一个ParkingLocation,所以您应该处理ParkingLocationsController#update中的Location添加。为了简单和一致,您的控制器不应该关心路由是PUT /locations/:location_id/parking_locations/:id还是PUT /parking_locations/:id。has_many关联提供ParkingLocation#location_ids=,您可以在任何您喜欢的表单中收集它并传递给控制器。您的update操作看起来与往常一样:
def update
@parking_location = ParkingLocation.find(params[:id])
if @parking_location.update(params[:parking_location])
redirect_to @parking_location
else
render :edit
end
end这样的请求将设置Location的1和2在ParkingLocation 3上。
PUT https://your.server/parking_locations/3?parking_location[location_ids[]]=1&parking_location[location_ids[]]=2如果您想要追加Location,您需要自己编写更多的代码来处理。如果您想在Location表单中创建ParkingLocation (反之亦然),您将需要查看Rails的嵌套形式特性。
https://stackoverflow.com/questions/34205418
复制相似问题