Zapisywanie danych do tabeli z "niebezpiecznymi" nazwami kolumn

Mam następujący problem:

do tabli, która posiada kolumnę o nazwie “hash” muszę zapisać pewną wartość, niestety ActiveRecord, ma metodę o nazwie hash i wyrzuca błąd ActiveRecord::DangerousAttributeError “hash is defined by Active Record”. Tabela używana jest przez inną aplikację, a chcę tylko wpisać rekord. Można uczywiście zrobić do za pomocą czystego sqla, ale czy da się to jakoś ładniej zapisać?

Pomysł bez testowania:

foo.write_attribute :hash, 'W4rT0$c'

To nic nie da, bo wywolujac create na modelu bez przekazania zadnych atrybutów bład nadal wyskakuje

Próbowałeś https://github.com/bjones/safe_attributes?

niestety nie działa w RoR 4

Jest powód dla którego jest to ostrzeżenie. nadpis\nie metody hash spowoduje że struktura Hash zgłupieje zupełnie. bo uzywa metody #hash i #eql? do sprawdzania czy to ten sam obiekt.

Moja rada to zamiast walić głową scianę zmienić nazwę kolumny. Jeżeli się nie da (baza jest uzywana przez inną aplikację), to w modelu robisz

def my_hash()
  read_attribute(:hash)
end

def my_hash=(value)
  write_attribute(:hash, value)
end

po czym już normalnie: Model.create(:my_hash => 1)

oczywiście zmienić my_hash na coś sensownego typu user_hash albo authentication_hash

@swistak84 w poście wyżej pisałem:

  1. baza wykorzystywana jest przez aplikacje trzecią i zmiana nazwy kolumny kompletnie odpada
  2. jesli to co napisałeś by działało to wywolanie Model.create (bez parametrów) też by działało, a wywołanie create bez parametrów nawet nie działa, chociaż sprawdzałem to o północy więc może ze zmęczenia coś przeoczyłem.

Co to za baza danych?

Pytam bo w normalnej bazie danych w ostateczności można zrobić widok ze zmienioną nazwą.

to jest baza mysql z vbulettina (tabela cpsession ma pole o nazwie hash), chce ta baze jak najmniej zmieniac, tzn tylko dodawac i usuwac pola i nic więcej, wszelakie modyfikacje tej bazy są w 99,999…% niewskazane.

http://www.java2s.com/Code/SQL/View/CreatingaViewwithSpecifiedColumnNames.htm

Jak powiedział swistak, spróbuj w ten sposób

Zdecydowanie poleciłbym widoki w bazie w takim razie:

https://dev.mysql.com/doc/refman/5.0/en/view-updatability.html

W mysql można tworzyć nawet Updatowalne widoki bez większych ceregieli, więc sposób najprostszy moim zdaniem.

Zdecydowałem się ostatecznie na rozwiązanie activemodel + raw sql zwłaszcza że tabela ma 3 kolumny (userid, hash, timeline). Z widokami jakoś nie mam doświadczenia a jak juz pisałem wyżej nie chce tykać za mocno tej bazy (zmieniać nazw, wprowadzać nowe table), bo to może w przyszłości dość mocno skomplikować upgrade te zewnętrznej aplikacji (zwłaszcza że na jej rozwój nie mam żadnego wpływu)

Więc temat nadaje się do zamknięcia.

Ja tam bym nadal zrobił widok. To o czym myslisz przyniesie ci tylko ból i nieszczęście (pod postacią brzydkich brzydkich modeli i sql injection).

Widok nie zmienia struktury bazy. Po prostu jest “nakładką” na tabele…

A co złego jest w czystym sql? Nie popadajmy w paranoję.

sql injection jest w sytuacji gdy przepuszczasz coś z widoku strony do modeli, a tutaj tego nie będzie, bo wszystko generowane jest na serwerze i jedyne zwracane.

Nie zagłębiając się w mniej i bardziej oczywiste zagrożenia, czysty sql to przede wszystkim dużo niepotrzebnej roboty którą można zrzucić np. na gema sequel (polecam).

sequela znam, ale uzywanie całego gema dla jednego zapytanie to jest już przesada. Poza tym problem już rozwiązany.

Ale ja nie pytałem o SQL w ogóle, tylko w tym konkretnym przypadku.