Korzystam z Ruby on Rails 3.2.2 i chciałbym wiedzieć, czy poniższe są „właściwym” / „poprawnym” / „pewnym” sposobem na przesłonięcie metody ustawiającej dla atrybutu mojej klasy.
attr_accessible :attribute_name
def attribute_name=(value)
... # Some custom operation.
self[:attribute_name] = value
end
Powyższy kod wydaje się działać zgodnie z oczekiwaniami. Jednak chciałbym wiedzieć, czy, stosując powyższy kod w przyszłości będę miał problemy, a przynajmniej, jakie problemy „należy się spodziewać” / „może się zdarzyć” z Ruby on Rails . Jeśli to nie jest właściwy sposób na zastąpienie metody setera, jaki jest właściwy sposób?
Uwaga : jeśli użyję kodu
attr_accessible :attribute_name
def attribute_name=(value)
... # Some custom operation.
self.attribute_name = value
end
Otrzymuję następujący błąd:
SystemStackError (stack level too deep):
actionpack (3.2.2) lib/action_dispatch/middleware/reloader.rb:70
Odpowiedzi:
================================================== ========================= Aktualizacja: 19 lipca 2017 r
Teraz dokumentacja Railsów również sugeruje użycie w
super
następujący sposób:================================================== =========================
Oryginalna odpowiedź
Jeśli chcesz zastąpić metody ustawiające dla kolumn tabeli podczas uzyskiwania dostępu przez modele, jest to odpowiedni sposób.
Zobacz Zastępowanie domyślnych akcesoriów w dokumentacji Railsów.
Tak więc twoja pierwsza metoda jest poprawnym sposobem na przesłonięcie ustawiaczy kolumn w modelach Ruby on Rails. Te akcesoria są już dostarczane przez Railsy, aby uzyskać dostęp do kolumn tabeli jako atrybuty modelu. Nazywamy to mapowaniem ORM ActiveRecord.
Należy również pamiętać, że
attr_accessible
górna część modelu nie ma nic wspólnego z akcesoriami. Ma zupełnie inną funkcjonalność (patrz to pytanie )Ale w czystym Rubim, jeśli zdefiniowałeś akcesory dla klasy i chcesz przesłonić setter, musisz użyć zmiennej instancji takiej jak ta:
Łatwiej będzie to zrozumieć, gdy dowiesz się, co
attr_accessor
robi. Kodattr_accessor :name
jest równoważny z tymi dwiema metodami (getter i setter)Również twoja druga metoda zawiedzie, ponieważ spowoduje nieskończoną pętlę, ponieważ wywołujesz tę samą metodę
attribute_name=
w tej metodzie.źródło
attr_accessible
ponieważ już go nie ma, i powinien działaćsuper
?super
mogą nie działać. Ale wydaje się, że tak nie jest. Właśnie to sprawdziłem i działa dla mnie. Także to pytanie zadaje to samowrite_attribute
. Konwersje zostaną pominięte. Pamiętaj, żewrite_attribute
pominie konwersje w strefie czasowej z datami, co prawie zawsze będzie niepożądane.Użyj
super
słowa kluczowego:I odwrotnie, aby zastąpić czytnik:
źródło
W szynach 4
powiedzmy, że masz atrybut wieku w tabeli
Uwaga: W przypadku nowych graczy w szynach 4 nie trzeba określać atrybutu attr_accessible w modelu. Zamiast tego musisz umieścić na białej liście swoje atrybuty na poziomie kontrolera, używając metody zezwolenia .
źródło
Przekonałem się, że (przynajmniej w przypadku kolekcji relacji ActiveRecord) działa następujący wzorzec:
(Spowoduje to pobranie pierwszych 3 niepowielonych wpisów w przekazanej tablicy).
źródło
Używanie
attr_writer
do nadpisywania setter attr_writer: nazwa_atrybutuźródło