2010-03-23 11 views
10

Próbuję odświeżać ciąg znaków, który wymaga danych wprowadzanych przez użytkownika, bez konieczności uciekania się do ręcznego tworzenia własnych, prawdopodobnie błędnych wyrażeń regularnych, jeśli to możliwe, jednak, jeśli jest to jedyny sposób, który byłbym wdzięczny, gdyby ktoś mógł wskazać mi właściwy kierunek do regexu, o którym raczej nie będzie brakować. Istnieje wiele metod w Railsach, które pozwalają na wprowadzanie natywnych poleceń SQL, w jaki sposób ludzie unikają wprowadzania danych przez użytkownika?Ruby on Rails: Jak oczyścić ciąg znaków dla SQL, gdy nie korzystasz z find?

Pytanie, które zadaję, jest szerokie, ale w moim konkretnym przypadku pracuję z kolumną w mojej bazie danych Postgres, że Rails nie rozumie natywnie, o ile mi wiadomo, tsvector, który jest prosty informacje wyszukiwania tekstowego. Railsy są w stanie napisać i odczytać z niego tak, jakby był ciągiem znaków, jednak w przeciwieństwie do łańcucha znaków, nie wydaje się, aby był on automatycznie uciekający, gdy robię rzeczy takie jak vector = wewnątrz modelu.

Na przykład, kiedy robię model.name = '::', gdzie nazwa jest ciągiem, działa dobrze. Kiedy zrobić model.vector = „::” it out błędy:

ActiveRecord::StatementInvalid: PGError: ERROR: syntax error in tsvector: "::" 
"vectors" = E'::' WHERE "id" = 1 

Wydaje się to być problem spowodowany brakiem ucieczki z średnikiem i mogę ręcznie ustawić wektor = „::” fine .

ja też miał świetny pomysł, może po prostu nazwać coś takiego:

ActiveRecord::Base.connection.execute "UPDATE medias SET vectors = ? WHERE id = 1", "::" 

jednak składnia ta nie działa, ponieważ surowe polecenia SQL nie mają dostępu do znalezienia sposobu na ucieczkę i wprowadzanie ciągów za pomocą? znak.

To uderza mnie jako ten sam problem, co wywołanie połączenia.execute z dowolnym typem danych wprowadzanych przez użytkownika, ponieważ wszystko sprowadza się do odkażania ciągów, ale nie mogę znaleźć sposobu na ręczne wywołanie ciągu SQL Railsów metody sanityzacji. Czy ktoś może udzielić jakiejkolwiek porady?

Odpowiedz

14

Dodaj tę metodę do modelu:

class Media < ActiveRecord::Base 
    def self.execute_sql(*sql_array)  
    connection.execute(send(:sanitize_sql_array, sql_array)) 
    end 
end 

Teraz można wykonać dowolny kod SQL, takich jak:

Media.execute_sql('UPDATE medias SET vectors = ? WHERE id = 1', '::') 

Reference

1) sanitize_sql_array

+1

Dzięki za cynk, działał dokładnie tak, jak powiedziałeś. Niestety, wygląda na to, że Railsy nie dezynfekują dwukropków (:) dla SQL, i wciąż dostaję błędy na tej linii. Być może wymaganie odkażania okrężnicy jest unikalne dla tsvektorów. Wygląda na to, że będę musiał pójść na skrzypiącą ścieżkę regex. –