ruby-on-rails Rails不允许JSON模式中的有效负载

wkyowqbh  于 2023-03-13  发布在  Ruby
关注(0)|答案(1)|浏览(151)

我正在试图弄清楚为什么我的Rails应用程序不允许我的属性,并且已经没有什么想法了。
我的数据库中有产品(型号Product),它们有一组适用于所有产品的标准属性。我有一个额外的JSONB列,称为dynamic_attributes,它特定于不同类型的产品。因此,我目前使用STI。
如果我试图编辑一个单独的记录,我会得到一个关于不允许的参数(我试图从编辑表单更新/修补的JSON参数)的错误。如果我删除.permit部分并只允许!everywhere,那么我不会得到任何错误,所有内容都会更新,但显然这并不理想。
STI的锁子类

class Lock < Product
  serialize :dynamic_attributes, JsonbSerializers
  store_accessor :dynamic_attributes, :kind, :interface
  validates :kind, presence: true

  def json_schema
    Rails.root.join('app', 'models', 'schemas', 'lock_category.json')
  end
end

它为所讨论的产品类型引用以下JSON模式:

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "required": [ "kind" ],
  "properties": {
    "kind": { 
      "type": "string",
      "enum": ["Cable", "Chain", "Folding", "Frame", "Part", "Padlock", "U-Lock", "U-Lock+Cable"]
    },
    "interface": {
      "type": "string",
      "enum": ["Key", "Combination", "Smart"]
    }
  }
}

产品控制器

def update
    @product = Product.find(params[:id])
    @product.update!(product_params)
    redirect_to @product
  end

private
  
  def product_params
    params.require(:product).
    permit(
      :type,
      :vendor,
      :description,
      :cost,
      :msrp,
      dynamic_attributes: [
        :kind,
        :interface
      ]
    )
  end
end

编辑表单是非常标准的,包含以下用于更新dynamic_attributes的部分:

<% @product[:dynamic_attributes].each do |k,v| %>
    <%= f.label k.to_sym %>  
    <%= f.text_field k.to_sym, :value => v %>
    <br />
  <% end %>

如果让我猜测(此时我所剩下的,我认为它可能是从数据库加载信息到编辑字段,然后再返回之间的事情。
尝试修补程序的日志:

Started PATCH "/products/0c092119-601c-4dbb-b05b-3ad5ac638631" for 127.0.0.1 at 2023-03-09 12:41:06 -0600
Processing by ProductsController#update as TURBO_STREAM
  Parameters: {"authenticity_token"=>"[FILTERED]", "product"=>{"vendor"=>"Vendor", "description"=>"First Lock", "cost"=>"37.5", "msrp"=>"74.99", "type"=>"Lock", "kind"=>"U-Lock", "interface"=>"Smart"}, "commit"=>"Update Product", "id"=>"0c092119-601c-4dbb-b05b-3ad5ac638631"}
  Product Load (0.3ms)  SELECT "products".* FROM "products" WHERE "products"."id" = $1 LIMIT $2  [["id", "0c092119-601c-4dbb-b05b-3ad5ac638631"], ["LIMIT", 1]]
  ↳ app/controllers/products_controller.rb:23:in `update'
Unpermitted parameters: :kind, :interface. Context: { controller: ProductsController, action: update, request: #<ActionDispatch::Request:0x00007fbba812f500>, params: {"_method"=>"patch", "authenticity_token"=>"[FILTERED]", "product"=>{"vendor"=>"Vendor", "description"=>"First Lock", "cost"=>"37.5", "msrp"=>"74.99", "type"=>"Lock", "kind"=>"U-Lock", "interface"=>"Smart"}, "commit"=>"Update Product", "controller"=>"products", "action"=>"update", "id"=>"0c092119-601c-4dbb-b05b-3ad5ac638631"} }
  TRANSACTION (0.1ms)  BEGIN
  ↳ app/controllers/products_controller.rb:24:in `update'
  Product Exists? (0.3ms)  SELECT 1 AS one FROM "products" WHERE "products"."vpn" = $1 AND "products"."id" != $2 AND "products"."vendor" = $3 LIMIT $4  [["vpn", "453"], ["id", "0c092119-601c-4dbb-b05b-3ad5ac638631"], ["vendor", "Vendor"], ["LIMIT", 1]]
  ↳ app/controllers/products_controller.rb:24:in `update'
  TRANSACTION (0.1ms)  COMMIT
  ↳ app/controllers/products_controller.rb:24:in `update'
Redirected to http://localhost:3000/products/0c092119-601c-4dbb-b05b-3ad5ac638631
Completed 302 Found in 7ms (ActiveRecord: 0.7ms | Allocations: 5365)
tsm1rwdh

tsm1rwdh1#

感谢@engineersmnky,他给出了答案:
kind和interface是不允许的,因为您声明它们应该嵌套在dynamic_attributes下,但在请求中它们没有嵌套。也许可以尝试更改此设置

f.text_field k.to_sym to f.text_field "dyanmic_attributes[#{k}]"

因此,我相应地更新了代码:

<% @product[:dynamic_attributes].each do |k,v| %>
    <%= f.label k.to_sym %>  
    <%= f.text_field "dynamic_attributes[#{k}]", :value => v %>
  <% end %>

相关问题