Szukam rozwiązania następującego problemu: Mam obiekt ActiveRecord, który jest wspierany przez aktualizowalny widok bazy danych (w DB2 za pośrednictwem pliku activerecord-jdbc -klejnotu rozdziału). Ten widok zawiera jedną kolumnę, która jest obliczana z innych kolumn i jest "tylko do odczytu": nie można ustawić tej kolumny w jakikolwiek prawidłowy sposób. Po utworzeniu nowego rekordu dla tego obiektu należy ustawić to pole jako , a nie. Jednak domyślnie ActiveRecord ustawia go na 'default' (NULL), który jest odrzucany przez bazę danych.Ignoruj kolumnę "tylko do odczytu" podczas tworzenia i aktualizowania w Ruby ActiveRecord
attr_readonly nie jest rozwiązaniem, ponieważ wyklucza tylko kolumnę z aktualizacji, a nie z plików create.
attr_ignore, taki jak zaimplementowany przez klejnot "lincoln", również nie jest rozwiązaniem, ponieważ wtedy pole jest całkowicie ignorowane. Jednak kolumna musi zostać przeczytana i być dostępna. Jest nawet używany jako część relacji.
Istnieją sposoby, aby uniemożliwić ustawienie pewien atrybut jednostki ActiveRecord, ale zwykle nie zapobiega to atrybut z wliczone jest w tworzenie lub oświadczenia aktualizacji
Czy ktoś wie, czy istnieje sposób, w ActiveRecord, aby określić kolumnę jako "nigdy nie ustawiaj tego pola"?
Aktualizacja, w odpowiedzi na Arsen7: Podjęto próbę użycia haka after_initialize w celu usunięcia atrybutu z nowo utworzonego obiektu, więc nie jest on zawarty w wbudowanym SQL. Problem polega na tym, że atrybut jest całkowicie usunięty i nie jest już dostępny, prawie identyczny z opisaną powyżej sytuacją "igonre_attr". Z powodu buforowania nie jest to łatwe do przejścia i wymagałoby dodatkowej logiki wymuszającej ponowne ładowanie jednostek tych tabel. Można to prawdopodobnie osiągnąć, przesyłając create
, aby dodać "przeładowanie", oprócz użycia funkcji after_initialize.
(Jak podkreślił Arsen7, zapomniałem wspomnieć, że jestem w ActiveRecord 3.0.9)
Moje rozwiązanie
Ponieważ moje podmioty już dziedziczyć z podklasy ActiveRecord::Base
, mam postanowił dodać haki before_create
i after_create
. W haku before_create
usuwam kolumny "obliczone" z @attributes
instancji. W haku after_create
dodaję je ponownie i odczytuję wartości "wyliczonych" kolumn z bazy danych, aby ustawić je na wartości, które otrzymały.
Dodanie takich haczyków jest niemal identyczne jak nadpisanie, dlatego uważam odpowiedź Arsen7 za poprawną.
Jeśli o przepisanie „tworzyć” Nie sugeruję usunięcie atrybutu z obiektu, po prostu sugerować tworzyć (i wykonanie) SQL bez określonej kolumnie. Ale co z wyzwalaczami? Wygląda jak najbardziej eleganckie rozwiązanie - twoje zapytanie zostanie przepisane przez bazę danych - tam możesz usunąć tę kolumnę tylko do odczytu z ostatecznego zapytania. – Arsen7
Podoba mi się pomysł wyzwalaczy, ale wadą jest to, że pole obliczeniowe należy zaktualizować, gdy zmieni się jedno z pól "źródła". Zasadniczo obliczone pole działa tak samo, jak wiele wyzwalaczy na wielu innych polach. Jako taki jest nieco prostszy niż wiele wyzwalaczy. Jeśli chodzi o modyfikowanie "tworzenia" (i być może "aktualizowania"): wolę powyżej modyfikację metody, która buduje SQL, ponieważ ta ostatnia znajduje się głębiej w miskach ActiveRecord. Zmiany na wyższym poziomie są zwykle łatwiejsze do zrozumienia. Jednak nadal muszę to zrobić i może się okazać, że się mylę :) – Confusion