[RoR] Hash zu Conditions-Array für Model.find() konvertieren
Vielleicht kann ja jemand diese Funktion gebrauchen, mir hat sie bei mehreren Filtermethoden sehr geholfen, da ich nur noch neue Formularfelder einfügen musste, um die Suche zu erweitern, den Rest hat die Funktion übernommen.
Ich bin mir sicher, es gibt einfachere Wege, um das zu erreichen, aber so hat es jedenfalls funktioniert.
Nutzungsbeispiel:
1 2 3 4 5 | #params[:search_details] muss ein hash sein, dessen key jeweils dem tabellen-feldnamen entspricht (also z.B. <input name="search_details[table.fieldname]" type="text" /> conditions = hash2conditions params[:search_details], { :additional => "table.canceled <> 1", :compare => "LIKE"} ... @list = Model.find(:all, :conditions => conditions) |
Sonderfall: Concat
In manchen Fällen kann es sinnvoll sein, nach einem Zusammengesetzen Datenbankfeld zu fahnden, beispielsweise, wenn Vor- und Zuname einer Person in unterschiedlichen Feldern gespeichert werden. In diesem Fall muss der key des hashs (= der Name des Textfeldes) folgendermaßen aufgebaut sein:
1 2 | hash = { "vorname| |zuname" => "max mustermann"} # => ["LOWER(CONCAT(vorname, ' ', zuname)) LIKE ?", "max mustermann"] |
Hilfs- und Hauptfunktion:
1 2 3 4 | #Benötigte Funktion zum escapen des SQL-Statements def mysql_escape_string string string.gsub(/["';]/, "") end |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | #konvertiert einen hash in ein conditions-array für Model.find() def hash2conditions _hash, options = { :compare => "LIKE", :additional => ""} conditions = {} conditions[:fields] = [] conditions[:values] = [] if _hash _hash.each do |key, value| #sql-injections verhindern key = mysql_escape_string key _hash[key] = mysql_escape_string _hash[key] unless _hash[key].blank? #Wenn compare-methode "like" und der wert kein Integer ist if options[:compare].downcase == "like" and _hash[key].to_i.to_s != _hash[key] #Concat, zusammengesetzte Werte, wie z.B. contacts.first_name + " " + "contacts.last_name" if key.split("|").size > 1 field = "LOWER(CONCAT(" + key.split("|").join(",").gsub(" ", "' '") + ")) " + options[:compare] + " ?" else field = "LOWER(" + key + ") " + options[:compare] + " ?" end value = "%" + _hash[key].downcase + "%" else #Integer-Wert, = wird in jedem fall genommen if _hash[key].to_i.to_s == _hash[key] field = key + " = ?" else field = key + " " + options[:compare] + " ?" end value = _hash[key] end if _hash[key] == "NULL" field = key + " IS NULL" value = "" end conditions[:fields] < < field conditions[:values] << value unless value.blank? end end end #addional-wert an conditions anfügen conditions[:fields] << options[:additional] unless options[:additional].blank? conditions[:fields] = conditions[:fields].join(" AND ") array = [] #conditions-array bilden array << conditions[:fields] conditions[:values].each do |value| array << value end return array end |
Kommentar verfassen
Statische Seiten
Kategorien
- Allgemein (13)
- Filme (7)
- Fun (16)
- Ireland (24)
- Musik (7)
- Programmierung (6)
- Uni (20)
- Mitschriften (15)
- WS 09/10 (13)
- Mitschriften (15)
- Windows / Linux (6)
Archive
- Februar 2012 (3)
- März 2011 (1)
- Februar 2011 (3)
- Juli 2010 (1)
- April 2010 (1)
- März 2010 (1)
- Februar 2010 (4)
- Januar 2010 (11)
- Dezember 2009 (3)
- November 2009 (2)
- September 2009 (3)
- August 2009 (9)
- Juli 2009 (2)
- Mai 2009 (1)
- April 2009 (2)
- März 2009 (4)
- Februar 2009 (6)
- Januar 2009 (6)
- Dezember 2008 (14)
- November 2008 (6)
- Oktober 2008 (13)
Letzte Kommentare
- Stex bei Über
- Annika bei Über
- Stex bei [JS] Ein einzelnes Div abdunkeln
- oliver bei [JS] Ein einzelnes Div abdunkeln
- CDU-Hasser bei MX5000 Functions

