gpt4 book ai didi

ruby-on-rails - Rails 5.1 API - 如何允许嵌套 JSON 对象的属性的参数

转载 作者:行者123 更新时间:2023-12-04 01:05:07 27 4
gpt4 key购买 nike

关于这个主题至少有 10 个问题,但没有一个回答这个特定问题。许多问题都与 Rails 表单有关,例如 this ,我没有,或者更复杂的 json 结构,比如 thisthis .

编辑关于接受的答案以及为什么这不是完全重复的

@CarlosRoque 的答案中的链接问题最初看起来是同一个问题,但它只解决了这个特定问题的 Rails 方面。

如果您阅读所有评论,您将看到多次尝试更改 template_params方法使用“template_items_attributes”重命名或替换嵌套属性“template_items”。这是必要的,因为 Rails accepts_nested_attributes_for要求在名称后附加“_attributes”,否则看不到它。

如果您检查该答案中的猴子补丁代码以修复 wrap_parameters 以便它适用于嵌套属性,您仍然会遇到问题,它实际上不会找到“template_items”(嵌套对象),因为它没有后缀“_attributes” ”。

因此,要完全解决这个问题,还必须修改客户端以将嵌套对象作为“template_items_attributes”发送。对于 JS 客户端,这可以通过在对象上实现 toJSON() 方法以在序列化期间修改它来完成(例如 here)。但请注意,当您反序列化 JSON 时,您将需要手动创建该对象的实例以使 toJSON() 工作(解释了为什么 here )。

我有一个简单的 has_many/belongs_to:

型号:

class Template < ApplicationRecord
belongs_to :account
has_many :template_items
accepts_nested_attributes_for :template_items, allow_destroy: true
end


class TemplateItem < ApplicationRecord
belongs_to :template
validates_presence_of :template

enum item_type: {item: 0, heading: 1}
end

客户端发送的 json 如下所示:
{
"id": "55e27eb7-1151-439d-87b7-2eba07f3e1f7",
"account_id": "a61151b8-deed-4efa-8cad-da1b143196c9",
"name": "Test",
"info": "INFO1234",
"title": "TITLE1",
"template_items": [
{
"is_completed": false,
"item_type": "item"
},
{
"is_completed": false,
"item_type": "heading"
}
]
}

有时会有 :id和一个 :content每个 template_item 中的属性(例如,在它们被创建并且用户开始编辑它们之后)。
template_params templates_controller的方法看起来像这样:
   params.require(:template).permit(
:id, :account_id, :name, :title, :info,
template_items: [:id, :is_completed, :content, :item_type]
)

如果这是一个 Rails 表单,那么该行将是:
   params.require(:template).permit(
:id, :account_id, :name, :title, :info,
template_items_attributes: [:id, :is_completed, :content, :item_type]
)

用于将嵌套的子对象保存为父模板更新操作的一部分。

我尝试更改嵌套参数名称:
def template_params
params.require(:template).permit(:id, :account_id, :name, :title, :info, template_items: [:id, :is_completed, :content, :item_type])
params[:template_items_attributes] = params.delete(:template_items) if params[:template_items]
Rails.logger.info params
end

我可以看到它们仍然不被允许:
{  
"template" =><ActionController::Parameters {
"id" =>"55e27eb7-1151-439d-87b7-2eba07f3e1f7",
"account_id" =>"a61151b8-deed-4efa-8cad-da1b143196c9",
"name" =>"Test",
"info" =>"INFO1234",
"title" =>"TITLE1",
} permitted:false >,
"template_items_attributes" => [
<ActionController::Parameters {
"is_completed" =>false,
"item_type" =>"item"
} permitted:false >,
<ActionController::Parameters {
"is_completed" =>false,
"item_type" =>"item"
} permitted:false >
]
}

我也尝试合并:
template_params.merge! ({template_items_attributes:
params[:template_items]}) if params[:template_items].present?

同样的问题。

那么我怎样才能确保它们被允许并包含在 template_params 中而不只是做 .permit ! (即。我不想盲目地允许一切)?

Controller 更新方法:
def update
Rails.logger.info "*******HERE*******"
Rails.logger.info template_params
@template.template_items = template_params[:template_items_attributes]

if @template.update(template_params)
render json: @template
else
render json: ErrorSerializer.serialize(@template.errors), status: :unprocessable_entity
end
end

UDPATE

如果我从客户端发送“template_items_attributes”而不是参数中的“template_items”到Rails,然后像这样执行推荐的template_params:
    def template_params
params.require(:template).permit(:id, :account_id, :name, :title, :info, template_items_attributes: [:id, :is_completed, :content, :item_type])
end

它仍然没有为模板创建新的 child !

有了这个,我输出前后的参数,如下所示:
def update
Rails.logger.info params
Rails.logger.info "*******HERE*******"
Rails.logger.info template_params

if @template.update(template_params)
render json: @template
else
render json: ErrorSerializer.serialize(@template.errors), status: :unprocessable_entity
end
end

这是这个场景的日志 - Rails 仍然完全忽略嵌入式数组。请注意,就在 HERE 之前的 params 显示 allowed: false ,然后 template_params 不再包含子项“template_items_attributes”并标记为 allowed:true。
I, [2017-10-20T21:52:39.886104 #28142]  INFO -- : Processing by Api::TemplatesController#update as JSON
I, [2017-10-20T21:52:39.886254 #28142] INFO -- : Parameters: {"id"=>"55e27eb7-1151-439d-87b7-2eba07f3e1f7", "account_id"=>"a61151b8-deed-4efa-8cad-da1b143196c9", "name"=>"Test", "info"=>"INFO12345", "title"=>"TITLE1", "created_at"=>"2017-10-14T19:30:41.450Z", "updated_at"=>"2017-10-20T17:48:24.909Z", "template_items_attributes"=>[{"is_completed"=>false, "item_type"=>"item"}], "template"=>{"id"=>"55e27eb7-1151-439d-87b7-2eba07f3e1f7", "account_id"=>"a61151b8-deed-4efa-8cad-da1b143196c9", "name"=>"Test", "info"=>"INFO12345", "title"=>"TITLE1", "created_at"=>"2017-10-14T19:30:41.450Z", "updated_at"=>"2017-10-20T17:48:24.909Z"}}
D, [2017-10-20T21:52:39.903011 #28142] DEBUG -- : User Load (7.7ms) SELECT "users".* FROM "users" WHERE "users"."uid" = $1 LIMIT $2 [["uid", "rmcsharry+owner@gmail.com"], ["LIMIT", 1]]
D, [2017-10-20T21:52:40.072148 #28142] DEBUG -- : Template Load (1.4ms) SELECT "templates".* FROM "templates" WHERE "templates"."id" = $1 ORDER BY name ASC LIMIT $2 [["id", "55e27eb7-1151-439d-87b7-2eba07f3e1f7"], ["LIMIT", 1]]
I, [2017-10-20T21:52:40.083727 #28142] INFO -- : <ActionController::Parameters {"id"=>"55e27eb7-1151-439d-87b7-2eba07f3e1f7", "account_id"=>"a61151b8-deed-4efa-8cad-da1b143196c9", "name"=>"Test", "info"=>"INFO12345", "title"=>"TITLE1", "created_at"=>"2017-10-14T19:30:41.450Z", "updated_at"=>"2017-10-20T17:48:24.909Z", "template_items_attributes"=>[{"is_completed"=>false, "item_type"=>"item"}], "controller"=>"api/templates", "action"=>"update", "template"=>{"id"=>"55e27eb7-1151-439d-87b7-2eba07f3e1f7", "account_id"=>"a61151b8-deed-4efa-8cad-da1b143196c9", "name"=>"Test", "info"=>"INFO12345", "title"=>"TITLE1", "created_at"=>"2017-10-14T19:30:41.450Z", "updated_at"=>"2017-10-20T17:48:24.909Z"}} permitted: false>
I, [2017-10-20T21:52:40.083870 #28142] INFO -- : *******HERE*******
D, [2017-10-20T21:52:40.084550 #28142] DEBUG -- : Unpermitted parameters: :created_at, :updated_at
I, [2017-10-20T21:52:40.084607 #28142] INFO -- : <ActionController::Parameters {"id"=>"55e27eb7-1151-439d-87b7-2eba07f3e1f7", "account_id"=>"a61151b8-deed-4efa-8cad-da1b143196c9", "name"=>"Test", "title"=>"TITLE1", "info"=>"INFO12345"} permitted: true>
D, [2017-10-20T21:52:40.084923 #28142] DEBUG -- : Unpermitted parameters: :created_at, :updated_at
D, [2017-10-20T21:52:40.085375 #28142] DEBUG -- : (0.2ms) BEGIN
D, [2017-10-20T21:52:40.114015 #28142] DEBUG -- : Account Load (1.2ms) SELECT "accounts".* FROM "accounts" WHERE "accounts"."id" = $1 LIMIT $2 [["id", "a61151b8-deed-4efa-8cad-da1b143196c9"], ["LIMIT", 1]]
D, [2017-10-20T21:52:40.131895 #28142] DEBUG -- : Template Exists (0.8ms) SELECT 1 AS one FROM "templates" WHERE "templates"."name" = $1 AND ("templates"."id" != $2) AND "templates"."account_id" = 'a61151b8-deed-4efa-8cad-da1b143196c9' LIMIT $3 [["name", "Test"], ["id", "55e27eb7-1151-439d-87b7-2eba07f3e1f7"], ["LIMIT", 1]]
D, [2017-10-20T21:52:40.133754 #28142] DEBUG -- : (0.3ms) COMMIT
D, [2017-10-20T21:52:40.137763 #28142] DEBUG -- : CACHE Account Load (0.0ms) SELECT "accounts".* FROM "accounts" WHERE "accounts"."id" = $1 LIMIT $2 [["id", "a61151b8-deed-4efa-8cad-da1b143196c9"], ["LIMIT", 1]]
D, [2017-10-20T21:52:40.138714 #28142] DEBUG -- : (0.2ms) BEGIN
D, [2017-10-20T21:52:40.141293 #28142] DEBUG -- : User Load (1.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 FOR UPDATE [["id", "88de3be9-6d18-4687-ab80-d50f78638ca9"], ["LIMIT", 1]]
D, [2017-10-20T21:52:40.235163 #28142] DEBUG -- : Account Load (0.7ms) SELECT "accounts".* FROM "accounts" WHERE "accounts"."id" = $1 LIMIT $2 [["id", "a61151b8-deed-4efa-8cad-da1b143196c9"], ["LIMIT", 1]]
D, [2017-10-20T21:52:40.240997 #28142] DEBUG -- : SQL (1.4ms) UPDATE "users" SET "tokens" = $1, "updated_at" = $2 WHERE "users"."id" = $3 [["tokens", "{\"ryyymFZ7fpH50rMKArjZ2Q\":{\"token\":\"$2a$10$4jkgRe4LBPxJ8fQUOKCSausUi7DbIUD0bE.7ZRoOuTHrRuX6CaWOe\",\"expiry\":1509293414,\"last_token\":\"$2a$10$cpI.mz81JFjQT0J9acCCl.NdrEatI5l17GtrwrAfwyhyN3xRExcaC\",\"updated_at\":\"2017-10-15T17:10:16.996+02:00\"},\"Y2y0maUT5WYSfH6VZeORag\":{\"token\":\"$2a$10$8KERiIwlc3rX.Mdu.CW6wOMLDbVyB2PFCaBIlw7/LUxC3ITpYTISW\",\"expiry\":1509293475,\"last_token\":\"$2a$10$r6Xw6798T1P7UZlTbEaXoeBCl9oK2fMs72ppAtars8Ai/kaE6nE66\",\"updated_at\":\"2017-10-15T17:11:18.066+02:00\"},\"9Cy48CPVj3WhFkEBPUZQ1Q\":{\"token\":\"$2a$10$Qy4JOD8.jIcPhf93MqFCIelnVaA/ssE31w5DlL8MShDuMROsLSNuS\",\"expiry\":1509293942,\"last_token\":\"$2a$10$e6sxklrHRRD1C15Ix/MqQOfACuCMznmzUjF296cpO1ypWVvJ.JFJK\",\"updated_at\":\"2017-10-15T17:19:05.200+02:00\"},\"O5iufW0Gacqs9sIfJ9705w\":{\"token\":\"$2a$10$EkDf7.y3lY9D36lAwNHBGuct97M6/HGDvnrUsD72c8zCsfVd8y9c2\",\"expiry\":1509482450,\"last_token\":\"$2a$10$S0kHEvKxom2Qgdy0r.q0aeTSlSBFkqU4XZeY91n3RkkYkQykmmGVi\",\"updated_at\":\"2017-10-17T21:40:50.300+02:00\"},\"ETOadoEtoxcz6rR6Ced_dA\":{\"token\":\"$2a$10$8t01bWv/PsVojs3cazuSg..FWa9SZwq1/PUDfuN1S4yBxnMFv2zre\",\"expiry\":1509742360,\"last_token\":\"$2a$10$hveuajISXDOjHLm9EkVzvOd3pwKkqE1rQnIFBoojf0vgMLXV2EvVe\",\"updated_at\":\"2017-10-20T21:52:40.233+02:00\"}}"], ["updated_at", "2017-10-20 19:52:40.236607"], ["id", "88de3be9-6d18-4687-ab80-d50f78638ca9"]]
D, [2017-10-20T21:52:40.243960 #28142] DEBUG -- : (1.3ms) COMMIT
I, [2017-10-20T21:52:40.244504 #28142] INFO -- : Completed 200 OK in 358ms (Views: 1.0ms | ActiveRecord: 37.7ms)

最佳答案

我认为您忘记了 params.require(:template).permit( ... 是一种返回值的方法,当您稍后调用 params 对其进行修改时,您只会修改尚未被允许的参数。您想要什么要做的是交换执行参数操作时的顺序。

def template_params
params[:template][:template_items_attributes] = params[:template_items_attributes]
params.require(:template).permit(:id, :account_id, :name, :title, :info, template_items_attributes: [:id, :is_completed, :content, :item_type])
end

更新: wrap_parameters 是罪魁祸首,因为它没有在包装的参数中包含嵌套参数。这解决了这个问题

更新:这个答案实现了不同的解决方案
Rails 4 Not Updating Nested Attributes Via JSON

这是github中的一个长期开放请求!!疯了
https://github.com/rails/rails/pull/19254

更新:这终于在 AR 6 中合并了
https://github.com/rails/rails/commit/62b7ad46c0f3ff24980956daadba46ccb2568445

关于ruby-on-rails - Rails 5.1 API - 如何允许嵌套 JSON 对象的属性的参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46853637/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com