2016-03-21 8 views
0

Nehmen wir an, es gibt ein Modell namens User. Das hat das Attribut: Hobbys.Wie würde ich nach einem Modell mit einem Array in einem .where suchen?

user = User.first 
user.hobbies 
=> ["Bowling", "Cooking", "Knitting"] 

Wenn ich ein .where auf der Suche nach dem: Hobbys Attribut verwenden möchte, wie würde ich das tun? Ich bin mit postgresql und

:hobbies, :text, array:true 

User.where (Hobby: "Alles, was ich hier gesagt, String-Array, Hash") führt den Fehler

ActiveRecord::StatementInvalid: PG::InvalidTextRepresentation: ERROR: malformed array literal: 

Antwort

1

Denken Sie daran, dass Sie jede SQL verwenden, können Sie, indem eine Zeichenfolge where wollen, zB:

User.where("hobbies @> ARRAY['Bowling', 'Cooking', 'Knitting']") 

oder

User.where("hobbies && ARRAY['Bowling', 'Cooking', 'Knitting']") 

Postgres hat gute Dokumentation des array operators zur Verfügung.

+0

Würde irgendwas davon in 'WHERE Hobbies IN '(' Bowling ',' Kochen ',' Stricken ')' übersetzen? Das wäre die optimale Abfrage. –

+0

'COUNT' sagt Ihnen nicht die Länge des Arrays, aber es sagt Ihnen, wie viele * Zeilen * in einer Gesamtabfrage Rollup-up werden. Deshalb gibt es immer 1: Egal wie lang das Array ist, es gibt immer noch nur eine Zeile. Wahrscheinlich willst du 'array_length (hobbys, 1)'. Aber ich bin mir nicht wirklich sicher, was Sie versuchen, also könnte ich auf der falschen Spur sein. –

+1

Der Grund, warum Sie 'IN' hier nicht verwenden können, ist, weil' Hobbys' keine Zeichenfolge, sondern ein Array von Strings ist. Sie sollten stattdessen die Array-Operatoren verwenden. '@>' bedeutet "Hobbies" hat alle von "Bowling", "Kochen" und "Stricken". '&&' bedeutet, dass es mindestens eine davon gibt. –

0

Sie können versuchen, contains oder overlap von postgres_ext Juwel. Installieren Sie einfach die Edelstein- und dann Abfrage:

query = ["Bowling", "Cooking", "Knitting"] 

#With Overlap operator: 
User.where.overlap(hobbies: query) 

#or with Contains Operator 
User.where.contains(hobbies: query) 
+0

undefinierte Methode 'Überlappung 'für # . Das gleiche gilt für enthält: l –

+0

Ah, mein Schlechter! Du brauchst ['postgres_ext'] (https://github.com/dockyard/postgres_ext), damit dies funktioniert. – Babar

Verwandte Themen