Ponieważ Rails zapewnia strukturę pod względem MVC, naturalne jest, że użyjesz tylko kontenerów modelu, widoku i kontrolera, które są dla Ciebie dostarczone. Typowym idiomem dla początkujących (a nawet niektórych pośrednich programistów) jest wbicie całej logiki aplikacji do modelu (klasy bazy danych), kontrolera lub widoku.
W pewnym momencie ktoś zwraca uwagę na paradygmat „grubego modelu, chudego kontrolera”, a pośredni programiści pośpiesznie usuwają wszystko ze swoich kontrolerów i wrzucają do modelu, który staje się nowym koszem na logikę aplikacji.
Chude kontrolery to w rzeczywistości dobry pomysł, ale następstwem - umieszczenie wszystkiego w modelu, nie jest tak naprawdę najlepszym planem.
W Ruby masz kilka dobrych opcji na uczynienie rzeczy bardziej modułowymi. Dość popularną odpowiedzią jest użycie modułów (zwykle ukrytych lib
), które przechowują grupy metod, a następnie włączenie modułów do odpowiednich klas. Pomaga to w przypadkach, w których masz kategorie funkcjonalności, które chcesz ponownie wykorzystać w wielu klasach, ale funkcjonalność jest nadal teoretycznie dołączona do klas.
Pamiętaj, że kiedy dołączysz moduł do klasy, metody stają się metodami instancji klasy, więc nadal otrzymujesz klasę zawierającą mnóstwo metod, są one po prostu ładnie zorganizowane w wiele plików.
To rozwiązanie może działać dobrze w niektórych przypadkach - w innych przypadkach warto pomyśleć o użyciu klas w kodzie, które nie są modelami, widokami ani kontrolerami.
Dobrym sposobem na zastanowienie się nad tym jest „zasada pojedynczej odpowiedzialności”, która mówi, że klasa powinna być odpowiedzialna za jedną (lub niewielką liczbę) rzeczy. Twoje modele są odpowiedzialne za utrwalanie danych z aplikacji do bazy danych. Twoje kontrolery są odpowiedzialne za otrzymanie żądania i zwrócenie realnej odpowiedzi.
Jeśli masz koncepcje, które nie pasują do tych skrzynek (trwałość, zarządzanie żądaniami / odpowiedziami), prawdopodobnie zastanawiasz się, w jaki sposób modelowałbyś dany pomysł. Możesz przechowywać klasy nie modelowe w aplikacji / klasach lub w dowolnym innym miejscu i dodać ten katalog do ścieżki ładowania, wykonując:
config.load_paths << File.join(Rails.root, "app", "classes")
Jeśli używasz pasażera lub JRuby, prawdopodobnie chcesz również dodać swoją ścieżkę do chętnych ścieżek ładowania:
config.eager_load_paths << File.join(Rails.root, "app", "classes")
Najważniejsze jest to, że gdy dojdziesz do punktu w Railsach, w którym zadajesz to pytanie, nadszedł czas, aby pogłębić swoje kotlety Ruby i rozpocząć modelowanie klas, które nie są tylko klasami MVC, które Railsy domyślnie ci dają.
Aktualizacja: Ta odpowiedź dotyczy Railsów 2.x i nowszych.
Aktualizacja : użycie obaw zostało potwierdzone jako nowe domyślne w Rails 4 .
To zależy od natury samego modułu. Zwykle umieszczam rozszerzenia kontrolera / modelu w folderze / dotyczy w aplikacji.
/ lib jest moim preferowanym wyborem dla bibliotek ogólnego przeznaczenia. Zawsze mam przestrzeń nazw projektów w lib, w której umieszczam wszystkie biblioteki specyficzne dla aplikacji.
Rozszerzenia rdzenia Ruby / Rails zwykle mają miejsce w inicjalizatorach konfiguracji, tak że biblioteki są ładowane tylko raz na boostrapie Rails.
W przypadku fragmentów kodu wielokrotnego użytku często tworzę wtyczki (mikro), aby móc ich ponownie używać w innych projektach.
Pliki pomocnicze zwykle zawierają metody pomocnicze, a czasem klasy, gdy obiekt jest przeznaczony do pomocy przez pomocników (na przykład Form Builderów).
To jest naprawdę ogólny przegląd. Podaj więcej szczegółów na temat konkretnych przykładów, jeśli chcesz uzyskać bardziej spersonalizowane sugestie. :)
źródło
„ogromny” to niepokojące słowo ... ;-)
W jaki sposób kontrolery stają się ogromne? Na to powinieneś spojrzeć: idealnie, kontrolery powinny być cienkie. Wybierając ogólną regułę, sugeruję, że jeśli regularnie masz więcej niż, powiedzmy, 5 lub 6 linii kodu na metodę kontrolera (działanie), wtedy twoje kontrolery są prawdopodobnie zbyt tłuste. Czy istnieje duplikacja, która mogłaby przejść do funkcji pomocniczej lub filtra? Czy istnieje logika biznesowa, którą można by zepchnąć do modeli?
Jak twoje modele stają się ogromne? Czy powinieneś szukać sposobów na zmniejszenie liczby obowiązków w każdej klasie? Czy są jakieś typowe zachowania, które można wyodrębnić w miksy? Lub obszary funkcjonalności, które możesz delegować na klasy pomocnicze?
EDYCJA: Próbuję trochę rozszerzyć, mam nadzieję, że nie zniekształcisz niczego zbyt mocno ...
Pomocnicy: mieszkają
app/helpers
i służą głównie do uproszczenia widoków. Są albo specyficzne dla kontrolera (dostępne również dla wszystkich widoków dla tego kontrolera), albo ogólnie dostępne (module ApplicationHelper
w application_helper.rb).Filtry: Powiedzmy, że masz ten sam wiersz kodu w kilku akcjach (dość często, wyszukiwanie obiektu za pomocą
params[:id]
lub podobnego). To duplikowanie można najpierw wyodrębnić do oddzielnej metody, a następnie całkowicie z akcji, deklarując filtr w definicji klasy, npbefore_filter :get_object
. Patrz sekcja 6 w Poradniku ActionController Rails Niech deklaratywne programowanie będzie twoim przyjacielem.Modele refaktoryzacji są nieco bardziej religijne. Uczniowie wuja Boba zasugerują na przykład, że przestrzegasz Pięciu Przykazań SOLID . Joel i Jeff mogą zalecić bardziej „erotyczne” podejście, chociaż później wydawało się, że są nieco bardziej pojednani . Znalezienie jednej lub więcej metod w klasie, które działają na jasno zdefiniowanym podzbiorze jej atrybutów, jest jednym ze sposobów próby zidentyfikowania klas, które mogą być refaktoryzowane z modelu opartego na ActiveRecord.
Nawiasem mówiąc, modele Railsów nie muszą być podklasami ActiveRecord :: Base. Innymi słowy, model nie musi być analogiem tabeli, ani nawet być powiązany z czymkolwiek przechowywanym. Nawet lepiej, jeśli tylko
app/models
nazwiesz swój plik zgodnie z konwencjami Railsów (wywołaj #underscore na nazwie klasy, aby dowiedzieć się, czego będzie szukał Rails), Railsy go znajdą bezrequire
potrzeby.źródło
Oto doskonały wpis na blogu o refaktoryzacji grubych modeli, które wydają się wynikać z filozofii „cienkiego kontrolera”:
http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/
Podstawową wiadomością jest „Nie wyodrębniaj miksów z modeli tłuszczu”, zamiast tego użyj klas usług, autor podaje w tym celu 7 wzorców
źródło