86 Stimmen

Eine Zeichenkette wie einen Querystring in Ruby on Rails parsen

Ich habe einen String wie diesen:

"foo=bar&bar=foo&hello=hi"

Bietet Ruby on Rails Methoden, um dies zu parsen, als ob es ein Querystring ist, so dass ich einen Hash wie diese erhalten:

{
    :foo => "bar",
    :bar => "foo",
    :hello => "hi"
}

Oder muss ich sie selbst schreiben?

EDIT

Bitte beachten Sie, dass es sich bei der obigen Zeichenfolge nicht um einen echten Querystring einer URL handelt, sondern um eine Zeichenfolge, die in einem Cookie von Facebook Connect gespeichert wird.

176voto

Julik Punkte 7498

Die Antwort hängt von der Version von Rails ab, die Sie verwenden. Wenn Sie 2.3 oder später verwenden, verwenden Sie den eingebauten Parser von Rack für Params

 Rack::Utils.parse_nested_query("a=2") #=> {"a" => "2"}

Wenn Sie mit älteren Rails arbeiten, können Sie tatsächlich CGI::parse . Beachten Sie, dass die Handhabung von Hashes und Arrays von Modul zu Modul unterschiedlich ist, so dass Sie überprüfen müssen, ob die Daten, die Sie erhalten, für die von Ihnen gewählte Methode korrekt sind.

Sie können auch Folgendes einschließen Rack::Utils in Ihre Klasse aufnehmen, um einen schnellen Zugriff zu ermöglichen.

0 Stimmen

Wenn Sie ein params-Objekt erhalten möchten, wie es Rails für Sie bereitstellt, können Sie Folgendes tun: params = ActionController::Parameters.new(Rack::Utils.parse_nested_query("a=2"))

0 Stimmen

Weiß jemand, ob es möglich ist, zu vermeiden, dass die Abfrage-String-Parameterwerte in Strings umgewandelt werden? z.B. möchte ich dieses Verhalten: ```` Rack::Utils.raw_parse_nested_query("a=2") #=> {"a" => 2} ```

1 Stimmen

Das ist zwar meistens ganz nett: Es parst "a[]=&a[]=z" como {"a[]"=>["", "z"]} verwendet wird, während der Parser, der von ActionController::Base gibt zurück. {:a => ["z"]}

40voto

dombesz Punkte 7867

Die

CGI::parse("foo=bar&bar=foo&hello=hi")

Gibt Ihnen

{"foo"=>["bar"], "hello"=>["hi"], "bar"=>["foo"]}

Bearbeiten: Nach Angaben von Ryan Lang diese Version berücksichtigt mehrere Werte desselben Schlüssels, was nützlich ist, wenn Sie auch Arrays analysieren wollen.

Bearbeiten 2:

Als Ben weist darauf hin, dass dies möglicherweise nicht Arrays gut behandeln, wenn sie mit Ruby on Rails Stil Array-Notation formatiert sind. Die Schienen Stil Array Notation ist: foo[]=bar&foo[]=nop . Dieser Stil wird in der Tat korrekt behandelt mit Juliks Antwort .

Diese Version parst Arrays nur dann korrekt, wenn Sie die Parameter wie foo=bar&foo=nop .

2 Stimmen

Dies ist die einzige Implementierung, die ich versucht habe, die mehrere Instanzen von jedem Parameter behandelt - Danke!

8 Stimmen

Das Problem ist, dass die meisten Leute keine Arrays wollen und eine einfache Schlüssel=>Wert-Antwort erwarten

0 Stimmen

Die Antwort von @julik sollte akzeptiert werden. CGI::parse behandelt Array nicht korrekt

15voto

systho Punkte 1161

Bearbeiten: Wie bereits in den Kommentaren erwähnt, kann die Symolisierung von Schlüsseln Ihren Server zum Absturz bringen, wenn jemand Ihnen schaden will. Ich mache das immer noch oft, wenn ich an unauffälligen Anwendungen arbeite, weil es die Arbeit einfacher macht, aber ich würde es nicht mehr für Anwendungen mit hohem Einsatz tun

Vergessen Sie nicht, die Schlüssel zum Erreichen des gewünschten Ergebnisses zu symbolisieren

Rack::Utils.parse_nested_query("a=2&b=tralalala").deep_symbolize_keys

dieser Vorgang ist bei Duplikaten destruktiv.

8 Stimmen

Die Symbolisierung von benutzerdefinierten Schlüsseln ist eine schlechte Idee. Symbole sind nicht GC-fähig. Wenn also jemand Ihren Server mit einer Menge falscher Parameterschlüssel überschwemmt, wird der Prozessspeicher irgendwann erschöpft sein.

6 Stimmen

Ruby 2.2 wird jetzt GC-Symbole enthalten.

9voto

lokeshjain2008 Punkte 1839

Wenn Sie über die Urls sprechen, die verwendet werden, um Daten über die Parameter zu erhalten

> request.url
=> "http://localhost:3000/restaurants/lokesh-dhaba?data=some&more=thisIsMore"

Um dann die Abfrageparameter zu erhalten, verwenden Sie

> request.query_parameters
=> {"data"=>"some", "more"=>"thisIsMore"}

2voto

Arnold Roa Punkte 6775

Wenn Sie eine Raute wünschen, können Sie

Hash[CGI::parse(x).map{|k,v| [k, v.first]}]

9 Stimmen

CGI.parse(query).transform_values(&:first)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X