64 votes

Rails convertit les tableaux vides en nils dans les paramètres de la requête

J'ai une épine Dorsale modèle dans mon application qui n'est pas un plat typique de l'objet, c'est un grand objet imbriqué et nous stockons les des pièces imbriquées dans les colonnes de TEXTE dans une base de données MySQL.

J'ai voulu traiter le JSON de codage/décodage dans les Rails de l'API, de sorte que de l'extérieur il ressemble, vous pouvez POST/GET ce un grand imbriquée objet JSON, même si certaines parties sont stockées en tant que stringified JSON texte.

Cependant, j'ai couru dans un problème où les Rails comme par magie convertit des tableaux vides à l' nil valeurs. Par exemple, si je POSTE ce:

{
  name: "foo",
  surname: "bar",
  nested_json: {
    complicated: []
  }
}

Mon Rails contrôleur voit ceci:

{
  :name => "foo",
  :surname => "bar",
  :nested_json => {
    :complicated => nil
  }
}

Et donc, mes données JSON a été modifié..

Quelqu'un a rencontré ce problème avant? Pourquoi Rails de modifier mon POST de données?

Mise à JOUR

C'est là où ils le font:

https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/http/request.rb#L288

Et voici ~pourquoi ils le font:

https://github.com/rails/rails/pull/8862

Alors maintenant, la question est de savoir comment gérer cela dans mon imbriquée API JSON situation?

45voto

a10s Points 307

Après beaucoup de recherches, j'ai découvert que vous commencer dans les Rails 4.1, vous pouvez sauter le deep_munge "fonctionnalité" complètement à l'aide de

config.action_dispatch.perform_deep_munge = false

Je ne pouvais pas trouver toute la documentation, mais vous pouvez voir l'introduction de cette option ici: https://github.com/rails/rails/commit/e8572cf2f94872d81e7145da31d55c6e1b074247

Il est possible d'un risque de sécurité en procédant de la sorte, documentée ici: https://groups.google.com/forum/#!topic/au système rubyonrails-sécurité/t1WFuuQyavI

11voto

latentflip Points 718

Ressemble à ce qui est connu, récemment introduit la question: https://github.com/rails/rails/issues/8832

Si vous savez où le tableau vide sera vous pouvez toujours params[:...][:...] ||= [] avant le filtre.

Vous pouvez également modifier votre épine Dorsale du modèle JSON méthode, explicitement stringifying la nested_json valeur à l'aide d' JSON.stringify() avant qu'il soit affiché manuellement et de l'analyser en arrière à l'aide de JSON.parse dans before_filter.

Moche, mais ça marchera.

9voto

Grandpa Points 1815

Vous pouvez ré-analyser les paramètres vous-même, comme ceci:

 class ApiController
  before_filter :fix_json_params

  [...]

  protected

  def fix_json_params
    if request.content_type == "application/json"
      @reparsed_params = JSON.parse(request.body.string).with_indifferent_access
    end
  end

  private

  def params
    @reparsed_params || super
  end
end
 

Cela fonctionne en recherchant les demandes avec un type de contenu JSON, en analysant à nouveau le corps de la demande, puis en interceptant la méthode params pour renvoyer les paramètres analysés s'ils existent.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X