【问题标题】:Rails 5 API - parent 'must exist' error when trying to create a child record via POSTRails 5 API - 尝试通过 POST 创建子记录时出现父“必须存在”错误
【发布时间】:2018-04-09 02:31:53
【问题描述】:

我正在 Rails 5 中构建我的第一个 API(有史以来)作为学习体验。

我在 --api 模式下使用 Rails 并安装了 active_model_serializers gem。

API 基于船舶和航次之间的关系。

一艘船 has_many :voyages 和一个航程 belongs_to :ship。

使用 Postman 检查 voyages API 端点,我将其作为返回值:

{
  "id": 1,
  "tstd_id": 94583,
  "year": 1722,
  "began": null,
  "trade_began": null,
  "departed_africa": null,
  "arrived_slaves": null,
  "ended": null,
  "length": null,
  "middle_passage_length": null,
  "port_departed": "Liverpool",
  "ship": {
    "id": 1,
    "name": "Mary",
    "flag": "British",
    "rig": null,
    "tonnage": null,
    "standardized_tonnage": null,
    "year_constructed": null,
    "place_registered": null,
    "year_registered": null,
    "from": null,
    "to": null
  }
}

当我尝试通过 POST 使用 Key: voyage[ship][id] Value: 1 创建一个新航程时,我从 API 中获得了“必须存在”的返回

我从 Rails 控制台得到的错误是:

Started POST "/voyages" for 127.0.0.1 at 2016-07-28 11:03:47 +0100
Processing by VoyagesController#create as */*
Parameters: {"voyage"=>{"ship"=>{"id"=>"1"}, "year"=>"4"}}
Unpermitted parameter: ship
(0.2ms)  begin transaction
(0.1ms)  rollback transaction
[active_model_serializers] Rendered ActiveModel::Serializer::Null with ActiveModel::Errors (0.14ms)
Completed 422 Unprocessable Entity in 9ms (Views: 0.9ms | ActiveRecord: 0.4ms)

我们将不胜感激。

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-5 active-model-serializers


    【解决方案1】:

    如果您已经拥有船的id,那么您必须将其发送为ship_id 而不是ship[id]。你的参数应该是这样的,

    { "voyage"=> { "ship_id" => "1", "year" => "4" } }
    

    【讨论】:

    • 不幸的是,当通过 POST 传递 ship_id 而不是 ship[id] 时,我遇到了完全相同的错误。参数按照您的建议返回,但我在控制台中收到了一个未经许可的参数 ship_id。
    • 这是因为我的控制器允许参数列表中没有 ship_id - 哎呀!谢谢!
    【解决方案2】:

    在没有父母限定的情况下创建新对象时我也看到了这个问题,例如:

    @obj = SomeObjectType.where(:some_parent_id => params[:some_parent_id]).first_or_create
    @obj.save!
    

    如果 SomeObjectType 有多个父级,例如一个用户,这也会以同样的方式出错,在大多数示例中通常以以下方式创建:

    @obj = User.find_by_id(params[:user_id]).objs.new(obj_params)
    @obj.save!
    

    在第一种出错的情况下,您必须通过 belongs_to 关系分配用户(或任何出错的父级):

     @obj = SomeObjectType.where(:some_parent_id => params[:some_parent_id]).first_or_create
     @user = User.find_by_id(params[:user_id]);
     @obj.user = @user
     @obj.save!
    

    可能有一种更简洁的方式来关联这些父母,但这解决了列出的问题。

    【讨论】:

      猜你喜欢
      • 2017-10-13
      • 1970-01-01
      • 2021-05-22
      • 1970-01-01
      • 2022-10-19
      • 2016-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多