Rails: Können Sie diese SQL -Abfrage von MySQL in SQLite übersetzen?
-
22-10-2019 - |
Frage
Können Sie diesen Rails -Code für MySQL übersetzen:
def Customer.find_by_key(key)
Customer.find(:all, :conditions => "pre_name REGEXP '.*#{key}.*'
OR sur_name REGEXP '.*#{key}.*'
OR street REGEXP '.*#{key}.*'
OR zip REGEXP '.*#{key}.*'
OR city REGEXP '.*#{key}.*'
OR phone_1 REGEXP '.*#{key}.*'
OR phone_2 REGEXP '.*#{key}.*'
OR email REGEXP '.*#{key}.*'
OR company REGEXP '.*#{key}.*'")
end
zu SQLite3 Code?
Lösung
Das REGEXP
Die Funktion wird in SQLite3 nicht standardmäßig definiert, sondern Sie müssen schon ein bisschen Arbeit erledigen.
Stecken Sie dies in einen Initialisierer (zum Beispiel in einen Initialisierer config/initializers/sqlite_regexp.rb
), funktioniert mit Rails 3.1 (siehe unten für Rails 3.0):
require 'active_record/connection_adapters/sqlite3_adapter'
class ActiveRecord::ConnectionAdapters::SQLite3Adapter
def initialize(db, logger, config)
super
db.create_function('regexp', 2) do |func, pattern, expression|
regexp = Regexp.new(pattern.to_s, Regexp::IGNORECASE)
if expression.to_s.match(regexp)
func.result = 1
else
func.result = 0
end
end
end
end
Code gestohlen hier.
Sie könnten natürlich Ihre Abfrage wie in der Antwort von @mU neu schreiben, aber ich dachte, es wäre schön zu wissen, wie man die Funktion wirklich implementiert.
Aktualisieren
Der obige Code funktioniert nicht für Rails 3.0, dies sollte funktionieren:
require 'active_record/base'
require 'active_record/connection_adapters/sqlite_adapter'
module ActiveRecord::ConnectionAdapters
class SQLite3Adapter < SQLiteAdapter
def initialize(db, logger, config)
super
db.create_function('regexp', 2) do |func, pattern, expression|
regexp = Regexp.new(pattern.to_s, Regexp::IGNORECASE)
if expression.to_s.match(regexp)
func.result = 1
else
func.result = 0
end
end
end
end
end
Andere Tipps
Diese ersetzen:
pre_name REGEXP '.*#{key}.*'
mit ähnlich:
pre_name LIKE '%#{key}%'
Oder besser, verwenden Sie Platzhalter:
:conditions => [
"pre_name LIKE :pattern OR sur_name LIKE :pattern ...",
{ :pattern => '%' + key + '%' }
]
Sqlite versteht Regexp, wird aber standardmäßig nicht implementiert, Sie müssen es selbst implementieren. Sie könnten Ihre Implementierung hinzufügen, aber es macht keinen Sinn, wenn Sie wahrscheinlich den Job machen werden.