RoR 6 API嵌套路由POST创建关联City时报province必须存在如何解决
问题原因
- 参数结构不符合要求:你的
city_params要求参数必须嵌套在city键下,但是你curl请求的body是把city、province放在顶层,所以这些参数根本没有被允许传入,@city的city和province_id都是空值。 - 关联字段名不匹配:你的参数里传的是
province: 1,但city_params只允许接收province_id字段,就算你把参数套对了层,province_id还是空值,关联校验就会报错。 - 额外说明:你在rails console里可以正常创建是因为你直接传入了
Province实例对象给province属性,ActiveRecord会自动处理关联赋值,而接口请求里你传入的是ID值,需要用province_id字段接收才能正确赋值关联。
解决方法
下面两种方案任选即可:
方案1:仅修改curl请求参数(改动最小)
把参数嵌套到city字段下,同时把province改成province_id,修改后的curl如下:
curl --location --request POST 'http://127.0.0.1:3000/provinces/1/cities' \ --header 'Content-Type: application/json' \ --data-raw '{ "city": { "city": "New City", "province_id": 1 } }'
方案2:利用嵌套路由自动获取省份ID(更规范,推荐)
嵌套路由下路径里的省份ID会被Rails自动放到params[:province_id]参数里,你可以直接在控制器里赋值,既不用用户传province_id,也避免了用户传错误的省份ID关联到其他省份的问题,修改控制器代码:
def create # 先从路由参数里找到对应的省份 @province = Province.find(params[:province_id]) # 直接通过关联创建城市,自动赋值province_id @city = @province.cities.new(city_params) if @city.save render json: @city, status: :created, location: @city else render json: @city.errors, status: :unprocessable_entity end end private def city_params # 这里可以去掉province_id的允许,不需要用户传该参数 params.require(:city).permit(:city) end
对应修改后的curl请求可以省略province相关参数:
curl --location --request POST 'http://127.0.0.1:3000/provinces/1/cities' \ --header 'Content-Type: application/json' \ --data-raw '{ "city": { "city": "New City" } }'
内容的提问来源于stack exchange,提问作者assembler
相关产品推荐
相关产品推荐

