2017-02-19 12 views
1

Я попытался использовать предложенный пример from github. Вы также можете найти его на некоторые ответы, как this one для Rails 4.Rails 5 - как включить белый список параметров для ENTIRE столбца 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 

но также не работает.

Атрибут: 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»? –

+0

@Pyro Ваш ответ решил. Спасибо! Я думаю, что сообщение об ошибке неперспекции может быть просто красной селедкой в ​​этом конкретном случае. – rmcsharry

ответ

3

Если я Правильно, вам все равно нужно permit! docume Параметр нт:

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 гарантирует, что метод permit! всегда может быть вызван, даже если не принят параметр document.

Под капотом 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