2017-11-27 2 views
0

Ein Benutzer hat languages, ein Array von Sprachnamen. Ich habe diese Methode:Wie man ein Array innerhalb einer SQL-Abfrage in Ruby einläuft

def get_users_by_filtered_langauges(lang) 
    users = [] 
    User.all.each do |u| 
    u.languages.each do |l| 
     users << u if lang.include?(l) 
    end 
    end 

die lang, eine Anordnung von Sprachnamen nimmt, und gibt die Benutzer, deren languages enthalten einige Sprache innerhalb lang. Beispiel: Wenn first_userlanguages["uk", "us"] und lang["uk"] ist, enthält der Rückgabewert der Methode first_user.

Gibt es eine Möglichkeit, dies zu minimieren und eine SQL-Abfrage auf einfachere Weise zu schreiben?

+0

Bitte zeigen Sie uns die Tabellenstruktur. Ist 'user.languages' nur ein serialisiertes Array-Feld in' users'? – mudasobwa

+0

Wenn 'languages' eine' has_many' Beziehung ist, sollten Sie in der Lage sein, etwas zu tun: 'User.joins (: languages) .where (languages: {name: langs})' – Amadan

Antwort

0
  1. alle Aufzeichnungen Auswahl ist immer ein Anti-Muster. Man sollte nur Datensätze von Interesse auswählen. Wenn Sie Probleme beim Schreiben der Abfrage haben, indem Sie nur relevante Datensätze auswählen, sollten Sie Ihre Datenbankstruktur überarbeiten.

  2. eine SQL-Abfrage auf einfache Art und Weise schreiben

, die relativ einfach ist. Für einzelne lang zu überprüfen wäre es:

%q|SELECT * FROM users WHERE languages LIKE "%#{lang}%"| 
  1. Selbst mit all wird Ihre Methode each zur Reduzierung des Eingangs zu missbrauchen.

in Ruby sollte es wie folgt geschrieben werden:

def get_users_by_filtered_langauges(*langs) 
    # single lang 
    # User.all.reject { |u| u.languages.include?(lang) } 

    # disjunction 
    User.all.reject { |u| (u.languages & langs).empty? } 
end 
+0

Danke. Das hat viel geholfen. –

+0

Haben Sie nicht streak doppelte Anführungszeichen (die für Kennungen in Standard-SQL, nicht Zeichenfolgen) in "LIKE" '% # {lang}%' "'? Wenn Sie ein serialisiertes Array haben, ist jede Abfrage gegen diese Spalte ein Wahnsinn; Wenn das Array eine PostgreSQL-Arrayspalte ist, müssen viele Operatoren verwendet werden. –

+0

@muistooshort in der Tat, danke, ich verlor in was ist SQL-String und was ist Ruby String, aktualisiert. Die Abfrage erfolgt gegen die einzelne Sprache; Da ich keine Ahnung von der zugrunde liegenden DB-Engine hatte, stellte ich die dritte Variante zur Verfügung. – mudasobwa

0

@ mudasobwa Antwort richtig ist. Aber du könntest das auch so machen.

User.where("languages like '%?%'", lang) 
+0

Dies ist kein gültiger Ruby. Du meintest wahrscheinlich "Sprachen wie '%?%'" '. – Amadan

+0

Richtig Danke. – Kamesh

Verwandte Themen