2017-02-19 1 views
1

J'ai essayé d'utiliser l'exemple suggéré from github. Vous pouvez également trouver sur des réponses comme this one pour Rails 4.Rails 5 - comment ajouter le param pour une colonne ENTRÉE jsonb postgres dans un contrôleur?

J'ai essayé cela dans Rails 5.0.1 et je reçois juste un hachage {} vide stocké dans la base de données:

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

Il est évident que si Je ne fais que permettre! Ça marche.

J'ai aussi essayé une réponse this question:

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

mais cela ne fonctionne pas non plus. L'attribut: document contient json qui n'est jamais le même entre les requêtes ... et est une structure longue et complexe.

J'ai juste besoin de le vider tel quel dans une colonne jsonb.

Pour les curieux, voici un exemple de ce qui peut être 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

Il semble qu'il y ait un PR exceptionnel pour fournir une solution facile à ce ici: https: // github.com/rails/rails/pull/26308 – rmcsharry

+0

Ce problème peut-il être lié à l'avertissement "Paramètre non autorisé: document" obtenu en essayant d'autoriser le paramètre 'document'? –

+0

@Pyro Votre réponse l'a résolu. Je vous remercie! Je pense que le message de paramètre non autorisé pourrait être juste un casse-tête dans ce cas particulier. – rmcsharry

Répondre

3

Si je suis correct, vous devez encore permit! le docume paramètre 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 

La façon dont cela fonctionne est qu'il ne gardera que le account_id au début, mais ensuite dans les tap nous ajoutons le paramètre document retour en essayant de le récupérer à partir des paramètres d'origine. ActionController::Parameters.new comme valeur par défaut pour fetch garantit que la méthode permit! est toujours appelable même si aucun paramètre document n'a été transmis.

Sous le capot ActionController::Parameters#permit! seems to recursively call the permit! function sur les paramètres contenus ainsi, afin que nous puissions l'appeler sur un exemple:

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

Merci pour l'explication détaillée. Cela fonctionne, merci. J'ai ajouté un commentaire à la question pour noter qu'il y a une solution dans une prochaine version de Rails pour simplifier la solution à ce problème. – rmcsharry