2017-02-19 41 views
1

我试图使用建议的示例from github。您也可以找到它像this one一些答案为Rails 4Rails 5 - 如何将控制器中整个jsonb postgres列的参数白名单?

我已经对Rails 5.0.1尝试这样做,我只是得到一个空的哈希{}存储在数据库中:

def proposal_params 
    params.require(:proposal).permit(:document, :account_id).tap do |whitelisted| 
    whitelisted[:document] = params[:proposal][:document] 
    end 
end 

显然,如果我只是允许!有用。

我也试着回答来自this question

def proposal_params 
    params.require(:proposal).permit(:account_id, document: Proposal.stored_attributes[:document]) 
end 

但也不能正常工作。

The:document属性包含json,它在请求之间永远不会相同......并且是一个漫长而复杂的结构。

我只需要将它转储到jsonb列。

对于好奇,这里是一个什么可以在document一个例子:

{ 
    "document":{ 
     "customer":{ 
     "id":"273a0ad1-0867-4c17-8e0a-3284c6f2f6af", 
     "first_name":"Ricardo", 
     "last_name":"Bird", 
     "email":"[email protected]", 
     "mobile":"07786560223" 
     }, 
     "state":8, 
     "salutation":"Mr & Mrs Bird", 
     "total_price":0, 
     "quoted_products":[ 
     { 
      "product":{ 
       "sku":"9111", 
       "name":"Solid European Oak", 
       "price":25.99, 
       "category":"Wood", 
       "sub_category":"Solid", 
       "updated_at":"2016-12-01", 
       "updated_by":"Donald Duck", 
       "created_at":"2016-11-01", 
       "created_by":"Mickey", 
       "image_url":"http://www.higherground.co.uk/wp-content/uploads/2015/11/wood-flooring-thumbnail.jpg" 
      }, 
      "total_price":25.99, 
      "total_area":1, 
      "product_total_price":25.99, 
      "is_manual_total":false, 
      "is_installed":false, 
      "install_price":null, 
      "are_rooms_grouped":false, 
      "rooms":[ 
       { 
        "name":"Dining Room", 
        "icon_url":"assets/fb-img/dining-room.png", 
        "number":null, 
        "area":1, 
        "width":null, 
        "length":null, 
        "subfloor_prep":null, 
        "subfloor_price":null, 
        "perimeter_product":null, 
        "perimeter_length":null, 
        "is_perimeter_installed":false, 
        "perimeter_price":null, 
        "perimeter_style":null, 
        "is_perimeter_remove_old":false, 
        "is_move_furniture":false, 
        "move_furniture_price":null, 
        "move_surcharge":null, 
        "stairs_stepcount":null, 
        "surcharge":null, 
        "is_installed":false, 
        "uplift_price":null, 
        "install_method":"bonded" 
       } 
      ], 
      "is_extras":true, 
      "threshold_count":2, 
      "radiator_count":3, 
      "trim_count":2, 
      "threshold_price":30, 
      "radiator_price":4, 
      "trim_price":10, 
      "is_rear_mat":false, 
      "is_front_mat":true, 
      "front_mat_type":"Coloured", 
      "rear_mat_type":null, 
      "front_mat_area":2, 
      "front_mat_price":60.01, 
      "rear_mat_area":null, 
      "rear_mat_price":null, 
      "extras_total_price":212.01999999999998 
     } 
     ], 
     "status":"Draft", 
     "is_details_oneprice":false, 
     "notes":"Testing submission" 
    } 
} 
+0

似乎有优秀的提供一个简单的解决方案,这这里PR:https://开头github.com/rails/rails/pull/26308 – rmcsharry

+0

这个问题可能与尝试允许'document'参数时获得的警告“Unpermitted parameter:document”有关吗? – 2017-02-19 23:10:59

+0

@Pyro你的答案解决了它。谢谢!我认为在这种特殊情况下,未经许可的参数信息可能只是一个红鲱鱼。 – rmcsharry

回答

3

如果我是正确的,你仍然需要permit!文件NT参数:

def proposal_params 
    params.require(:proposal).permit(:account_id).tap do |whitelisted| 
    whitelisted[:document] = params[:proposal].fetch(:document, ActionController::Parameters.new).permit! 
    end 
end 

其工作原理是,它只会保留account_id在第一,但随后内tap我们通过尝试从原来的参数检索它添加document参数后面。 ActionController::Parameters.new作为fetch的默认值可确保即使没有传递document参数,也始终可调用permit!方法。

在上载参数引擎盖ActionController::Parameters#permit! seems to recursively call the permit! function为好,这样我们就可以把它在任何实例:

def permit! 
    each_pair do |key, value| 
    Array.wrap(value).each do |v| 
     v.permit! if v.respond_to? :permit! 
    end 
    end 

    @permitted = true 
    self 
end 
+0

感谢您的详细解释。这工作,谢谢。我在这个问题中添加了一条评论,注意到未来版本的Rails中有一个解决方案可以简化这个问题的解决方案。 – rmcsharry

相关问题