2 Stimmen

Hinzufügen eines nicht-literalen Hash-Elements zu den magischen Hashes von Ruby mit letztem Argument?

Viele Rails-Helfer verwenden einen idiomatischen Options-Hash als letztes Argument; Ruby fügt automatisch zusätzliche Methodenargumente in diesen Hash ein. Oft möchte ich ein Element bedingt einfügen oder einen Helper schreiben, der das Element bereitstellt. Zwei Beispiele in Pseudo-Ruby:

link_to "Example 1", "http://www.example.com", needs_confirmation? ? :confirm => "Are you sure?" : nil    # syntax error; nil can't be a hash element

o

link_to "Example 2", "http://www.example.com", unique_link_id

# I don't want to return a hash; I want to return an element of a hash
def unique_link_id
  :id => "our_link_#{user.id}"    # Syntax error
  {:id => "our_link_#{user.id}"}  # valid, but returns a hash that ends up being an element of the options hash
  {:id => "our_link_#{user.id}"}.flatten_into_my_parent_hash  # What's in my brain
end

Gibt es eine elegante Möglichkeit, dies zu tun? Ich kann die Rails-Helfer nicht kontrollieren, offensichtlich, so kann ich nicht zwingen, den Hash zu glätten. (Äh, nicht, dass es eine Hash#flatten Methode, aber selbst wenn es eine gäbe.)

Ich kann den Hash als Variable vor dem Methodenaufruf erstellen, natürlich, und optional Elemente hinzufügen, aber... ick.

Nehmen wir an, dass es sich um erfundene Beispiele handelt, und gehen wir davon aus, dass die Helfer es nicht zulassen würden :confirm => nil o :id => nil und dass unique_link_id Vielleicht sollten Sie die ID weglassen. Ich bin mehr daran interessiert, in der Hash-Syntax als in ein Rails-Problem zu lösen.

Irgendjemand?

2voto

Nikos Punkte 1032

Ich denke, Sie sollten etwas wie das Folgende versuchen:

link_to "Example 1", "http://www.example.com", :confirm => needs_confirmation? ? "Are you sure?" : nil

Und für den zweiten Fall könnte man in ähnlicher Weise folgendes sagen:

link_to "Example 2", "http://www.example.com", :id=>unique_link_id

Hinweis: unique_link_id sollte einen String zurückgeben (oder nil, wenn Sie keine ID haben wollen)

Um Ihre Frage allgemein zu beantworten, müssen Sie verstehen, wie Rails diese Parameter behandelt, die Sie in einer Methode (z. B. einem Helper) übergeben.

Die meisten Schienenhilfsmittel beginnen auf diese Weise:

def a_helper(*args)
  options = args.extract_options!
  ...
end

Was Sie über die oben genannten Punkte wissen sollten: Es wird angenommen, dass ein Array als Parameter übergeben wird. Alle :something=>value, die Sie hinzufügen, werden in einen Hash umgewandelt, der das letzte Element dieses Arrays ist. Also extract_options! trennt die normalen Parameter von den Hash-Optionen. Also in der Reihenfolge, in der Sie arbeiten wollen, todos Optionen sollten in eine Hash am Ende.

Um eine lange Geschichte zu erzählen, hier ein Beispiel dafür, was Sie tun sollten:

 link_to "Example 1", "http://www.example.com",{:confirm=>"Are you sure?"}.merge(unique_link_id)

In diesem Fall unique_link_id gibt einen Hash zurück und wird mit den anderen Optionen zusammengeführt. Wenn unique_link_id gibt einen leeren Hash zurück( {} ) wird nichts zu Ihren Optionen hinzugefügt und alle sind zufrieden :)

Wenn Ihre Optionen zu kompliziert werden, schlage ich vor, dass Sie eine Optionsvariable erstellen, bevor Sie die gewünschte Hilfsfunktion (oder Methode) aufrufen. options sollte ein Hash sein, der beliebig oft mit anderen Hashes gemischt wird, bevor Sie ihn als letzten Parameter an Ihre Methode übergeben.

Tipp: sehr nützliche Hash-Funktionen sind hash.merge(), hash.merge!() und hash.reverse_merge()

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