Więc sam to odkryłem. To właściwie dość prosta, ale potężna koncepcja. Ma to związek z ponownym użyciem kodu, jak w poniższym przykładzie. Zasadniczo chodzi o to, aby wyodrębnić typowe i / lub kontekstowe fragmenty kodu, aby oczyścić modele i uniknąć ich nadmiernego zużycia i bałaganu.
Jako przykład podam jeden dobrze znany wzorzec, znakowalny wzór:
# app/models/product.rb
class Product
include Taggable
...
end
# app/models/concerns/taggable.rb
# notice that the file name has to match the module name
# (applying Rails conventions for autoloading)
module Taggable
extend ActiveSupport::Concern
included do
has_many :taggings, as: :taggable
has_many :tags, through: :taggings
class_attribute :tag_limit
end
def tags_string
tags.map(&:name).join(', ')
end
def tags_string=(tag_string)
tag_names = tag_string.to_s.split(', ')
tag_names.each do |tag_name|
tags.build(name: tag_name)
end
end
# methods defined here are going to extend the class, not the instance of it
module ClassMethods
def tag_limit(value)
self.tag_limit_value = value
end
end
end
Tak więc po przykładzie produktu możesz dodać Taggable do dowolnej klasy i udostępnić jego funkcjonalność.
Jest to dość dobrze wyjaśnione przez DHH :
W Railsach 4 zaprosimy programistów do używania problemów z domyślnymi katalogami app / models / koncernów / app / kontrolerów / koncernów, które są automatycznie częścią ścieżki ładowania. W połączeniu z otoką ActiveSupport :: Concern jest to wystarczające wsparcie, aby ten lekki mechanizm faktoringowy zabłysnął.
Czytałem o korzystaniu z modeli z modelami do modelowania tłuszczowych modeli, a także do OSUSZANIA kodów modeli. Oto wyjaśnienie z przykładami:
1) SUSZENIE kodów modeli
Rozważ model artykułu, model zdarzenia i model komentarza. Artykuł lub wydarzenie ma wiele komentarzy. Komentarz należy do artykułu lub wydarzenia.
Tradycyjnie modele mogą wyglądać następująco:
Model komentarza:
Model artykułu:
Model zdarzenia
Jak możemy zauważyć, znaczna część kodu jest wspólna zarówno dla zdarzenia, jak i artykułu. Korzystając z obaw, możemy wyodrębnić ten wspólny kod w osobnym module Komentowalny.
W tym celu utwórz plik commentable.rb w app / models / koncernach.
A teraz twoje modele wyglądają tak:
Model komentarza:
Model artykułu:
Model zdarzenia:
2) Modele tłuszczów wyróżniające skórę.
Rozważ model zdarzenia. Wydarzenie ma wielu uczestników i komentarzy.
Zazwyczaj model zdarzenia może wyglądać tak
Modele o wielu skojarzeniach i poza tym mają tendencję do gromadzenia coraz większej ilości kodu i stają się niemożliwe do zarządzania. Obawy stanowią sposób na zminiaturyzowanie modułów tłuszczu, dzięki czemu są one bardziej modułowe i łatwe do zrozumienia.
Powyższy model można refaktoryzować, korzystając z poniższych obaw: Utwórz a
attendable.rb
icommentable.rb
plik folderze app / models / koncern / eventattable.rb
commentable.rb
A teraz używając Obawy, Twój model wydarzenia zmniejsza się do
* Podczas korzystania zaleca się grupowanie oparte na „domenie”, a nie „techniczne”. Grupowanie w oparciu o domeny jest podobne do „Komentowalne”, „Photoable”, „Attendable”. Grupowanie techniczne oznacza „ValidationMethods”, „FinderMethods itp
źródło
def self.my_class_method
), metody instancji oraz wywołania metod i dyrektywy w zakresie klasy. Nie ma potrzebymodule ClassMethods
add_item
, na przykład, masz problemy . Pamiętam, że Railsy zostały zerwane, gdy niektóre weryfikatory przestały działać, ale ktoś wdrożyłany?
problem. Proponuję inne rozwiązanie: użyj troski jak interfejsu w innym języku. Zamiast definiować funkcjonalność, definiuje odwołanie do osobnego wystąpienia klasy, który obsługuje tę funkcjonalność. Potem masz mniejsze, zgrabniejsze klasy, które robią jedną rzecz ...Warto wspomnieć, że używanie obaw jest uważane przez wielu za zły pomysł.
Pewne powody:
include
metoda łatania , istnieje cały system obsługi zależności - zdecydowanie zbyt duża złożoność dla czegoś, co jest trywialnym, dobrym, starym wzorcem mieszania Ruby.Obawy są łatwym sposobem na zastrzelenie się w nogę, bądź z nimi ostrożny.
źródło
Ten post pomógł mi zrozumieć obawy.
źródło
Czułem, że większość przykładów pokazuje siłę,
module
a nieActiveSupport::Concern
wartość dodanąmodule
.Przykład 1: Bardziej czytelne moduły.
Więc bez obaw, jak typowy
module
będzie.Po refaktoryzacji za pomocą
ActiveSupport::Concern
.Widzisz metody instancji, metody klas i dołączony blok są mniej nieporządne. Obawy wstrzykną je odpowiednio dla ciebie. To jedna z zalet używania
ActiveSupport::Concern
.Przykład 2: Obsługuj zależności modułu z wdziękiem.
W tym przykładzie
Bar
jest moduł, któryHost
naprawdę potrzebuje. Ale skoroBar
zależnośćFoo
odHost
klasy musiinclude Foo
(ale poczekaj, dlaczegoHost
chce wiedziećFoo
? Czy można tego uniknąć?).Bar
Dodaje więc zależność wszędzie. I kolejność włączenia liczy również tutaj. To dodaje wiele złożoności / zależności do ogromnej bazy kodu.Po refaktoryzacji za pomocą
ActiveSupport::Concern
Teraz wygląda to prosto.
Jeśli zastanawiasz się, dlaczego nie możemy dodać
Foo
zależności wBar
samym module? To nie zadziała, ponieważmethod_injected_by_foo_to_host_klass
musi zostać wprowadzone do klasy, któraBar
nie obejmujeBar
samego modułu.Źródło: Rails ActiveSupport :: Koncern
źródło
W przypadku wątpliwości wykonaj plik nazwa_pliku.rb
Na przykład chcę w mojej aplikacji, w której istnieje atrybut create_by, zaktualizuj tam wartość o 1, a 0 dla updated_by
Jeśli chcesz przekazać argumenty w akcji
potem dołącz do swojego modelu w ten sposób:
źródło