Czytałem trochę o tym, jak rozszerzyć klasę ActiveRecord: Base, aby moje modele miały specjalne metody. Jak łatwo go rozszerzyć (samouczek krok po kroku)?
ruby-on-rails
extend
rails-activerecord
xpepermint
źródło
źródło
Odpowiedzi:
Istnieje kilka podejść:
Korzystanie z ActiveSupport :: Concern (preferowane)
Przeczytaj dokumentację ActiveSupport :: Concern, aby uzyskać więcej informacji.
Utwórz plik o nazwie
active_record_extension.rb
wlib
katalogu.Utwórz plik w
config/initializers
katalogu o nazwieextensions.rb
i dodaj następujący wiersz do pliku:Dziedziczenie (preferowane)
Zapoznaj się z odpowiedzią Toby'ego .
Łatanie małp (należy unikać)
Utwórz plik w
config/initializers
katalogu o nazwieactive_record_monkey_patch.rb
.Słynny cytat Jamiego Zawinskiego o wyrażeniach regularnych może zostać wykorzystany ponownie, aby zilustrować problemy związane z małpami łatania.
Łatanie małp jest łatwe i szybkie. Jednak zaoszczędzony czas i wysiłek są zawsze wycofywane w przyszłości; z odsetkami składanymi. Obecnie ograniczam patchowanie małp do szybkiego prototypowania rozwiązania w konsoli rails.
źródło
require
pliku na końcuenvironment.rb
. Dodałem ten dodatkowy krok do mojej odpowiedzi.ImprovedActiveRecord
i dziedziczyć po tym, kiedy używaszmodule
, aktualizujesz definicję danej klasy. Kiedyś korzystałem z dziedziczenia (przyczyna wieloletniego doświadczenia w Javie / C ++). Obecnie najczęściej używam modułów.Refinements
która rozwiązuje większość problemów z małpami łatania ( yehudakatz.com/2010/11/30/ruby-2-0-refinements-in-practice ). Czasami jest po to, by zmusić cię do kuszenia losu. A czasami to robisz.Możesz po prostu rozszerzyć klasę i po prostu użyć dziedziczenia.
źródło
abstract_models
. Gdzie mam to położyć?self.abstract_class = true
do swojegoAbstractModel
. Railsy będą teraz rozpoznawać model jako model abstrakcyjny.AbstractModel
w bazie danych. Kto by pomyślał, że prosty seter pomoże mi SUCHO! (Zaczynałem się wzdychać ... było źle). Dzięki Toby i Harish!Możesz także używać
ActiveSupport::Concern
i być bardziej idiomatycznym rdzeniem Rails, takim jak:[Edytuj] po komentarzu od @daniel
Następnie wszystkie modele będą miały metodę
foo
dołączoną jako metoda instancji, a metody w niejClassMethods
zawarte jako metody klas. Np.FooBar < ActiveRecord::Base
Będziesz mieć:FooBar.bar
iFooBar#foo
http://api.rubyonrails.org/classes/ActiveSupport/Concern.html
źródło
InstanceMethods
jest to przestarzałe od Railsów 3.2, po prostu umieść swoje metody w treści modułu.ActiveRecord::Base.send(:include, MyExtension)
inicjalizator i wtedy to zadziałało. Szyny 4.1.9W przypadku Rails 4, koncepcja wykorzystania zagadnień do modularyzacji i OSUSZANIA modeli była najważniejsza.
Obawy w zasadzie pozwalają na grupowanie podobnego kodu modelu lub w wielu modelach w jednym module, a następnie używanie tego modułu w modelach. Oto przykład:
Rozważmy model artykułu, model zdarzenia i model komentarzy. Artykuł lub wydarzenie ma wiele komentarzy. Komentarz należy do artykułu lub wydarzenia.
Tradycyjnie modele mogą wyglądać tak:
Model komentarzy:
Model artykułu:
Model zdarzenia
Jak możemy zauważyć, istnieje znaczący fragment kodu wspólny zarówno dla modelu zdarzenia, jak i artykułu. Korzystając z obaw, możemy wyodrębnić ten wspólny kod w oddzielnym module.
W tym celu utwórz plik commentable.rb w app / model / problems.
A teraz twoje modele wyglądają tak:
Model komentarzy:
Model artykułu:
Model zdarzenia
Jedną kwestią, którą chciałbym podkreślić podczas używania obaw, jest to, że obawy powinny być używane do grupowania „na podstawie domeny”, a nie grupowania „technicznego”. Na przykład grupowanie domen jest takie jak „Możliwość komentowania”, „Możliwość tagowania” itp. Grupowanie techniczne będzie wyglądać jak „FinderMethods”, „ValidationMethods”.
Oto link do posta, który okazał się bardzo przydatny do zrozumienia problemów w modelach.
Mam nadzieję, że napisanie pomoże :)
źródło
Krok 1
Krok 2
Krok 3
źródło
Rails 5 zapewnia wbudowany mechanizm przedłużania
ActiveRecord::Base
.Osiąga się to poprzez zapewnienie dodatkowej warstwy:
i wszystkie modele dziedziczą po nim:
Zobacz np. Ten post na blogu .
źródło
Żeby dodać do tego tematu, chwilę zastanawiałem się, jak przetestować takie rozszerzenia (poszedłem dalej
ActiveSupport::Concern
).Oto jak skonfigurowałem model do testowania moich rozszerzeń.
źródło
W Railsach 5 wszystkie modele są dziedziczone z ApplicationRecord i daje to dobry sposób na dołączanie lub rozszerzanie innych bibliotek rozszerzeń.
Załóżmy, że moduł metod specjalnych musi być dostępny we wszystkich modelach, dołącz go do pliku application_record.rb. Jeśli chcemy zastosować to do określonego zestawu modeli, uwzględnij go w odpowiednich klasach modeli.
Jeśli chcesz mieć metody zdefiniowane w module jako metody klasowe, rozszerz moduł do ApplicationRecord.
Mam nadzieję, że pomoże to innym!
źródło
mam
w inicjatorze
Dla modułu jak poniżej
źródło