2010-12-27 20 views
15

kod najpierw:Rails baz danych wartości logiczne

create_table :users do |t| 
    ... 
    t.boolean :is_active, :default => true 
    ... 
end 

Teraz tutaj jest mój problem - tworzę zadanie natarcia importować szereg DUŻY rekordów (10000). Zrobiłem obszerne testy i testy porównawcze i ustaliłem, że najszybszym i najbardziej efektywnym sposobem wykonania tego zadania jest utworzenie jednego gigantycznego surowego wyrażenia SQL. (Czytam dane z CSV). Na przykład:

inserts = Array.new 
FasterCSV.foreach(...) do |row| 
    inserts.push "(row[0], row[1]...)" 
end 
User.connection.execute "INSERT INTO users (...) VALUES #{inserts.join(", ")}" 

Wszystko działa świetnie. Cały proces trwa (dosłownie) sekund zamiast 1,5 godziny przy pomocy ActiveRecord. Jednak mój problem dotyczy pola boolowskiego. Rozwijam się lokalnie na SQLite, ale MySQL przy produkcji. Podczas korzystania z ActiveRecord, Railsy określają, co umieścić w polu "boolean" (ponieważ prawie wszystkie bazy danych są różne). Piszę niestandardowego SQL i chcę wiedzieć, czy istnieje sposób mogę zrobić coś takiego ...

INSERT INTO users(..., is_active, ...) VALUES (..., ActiveRecord::Base.connection.boolean.true, ...) 

... że poprawnie zwraca wartość logiczną bazy danych specyficznych.

Każdy, kto odpowie "tylko przy użyciu ActiveRecord", zostanie poddany pod głosowanie. Po prostu NIE jest to możliwe w tej sytuacji. Nie chcę również używać pola tinyint (1) i używać 1 lub 0.

Podsumowując, wartość is_active musi się zmienić w zależności od bieżącego połączenia z bazą danych ...

Czy to w ogóle możliwe?

+0

Dlaczego nie rozwijasz się lokalnie z MySQL? To rozwiązałoby ten problem, podobnie jak inne niezgodności. Sposób, w jaki zwykle radzę sobie z booleanami, polega na użyciu przygotowanego oświadczenia, ale nie będzie dla ciebie działał. –

+0

To jednak nie odpowiada na moje pytanie. Co jeśli chcę w pewnym momencie użyć POSTgres lub MSSQL? – sethvargo

Odpowiedz

31

wierzę, że może być szukasz ActiveRecord::Base.connection.quoted_true

zwraca To rodzimych wartości logicznych w cudzysłowie, np "1" dla SQL Server lub MySQL i "t" dla PostgreSQL lub SQLite

+0

Dziękuję bardzo! Jak/gdzie to znalazłeś ?! Warto również edytować odpowiedź (tylko dla innych osób, które mogą mieć ten problem), aby wspomnieć, że automatycznie zawiera ona cudzysłów ('). Na przykład, jeśli połączenie jest sqlite, zwraca "t" nie tylko t. – sethvargo

+2

Heh, aby go znaleźć, miałem trochę zabawy przeglądając kody dla adapterów połączeń ActiveRecord. – Scott

+1

Dla jasności: możesz użyć self.connection.quoted_ * w metodach klas i self.class.connection.quoted_ * w metodach instancji. –