Also habe ich es selbst herausgefunden. Es ist eigentlich ein ziemlich einfaches, aber leistungsstarkes Konzept. Dies hat mit der Wiederverwendung von Code wie im folgenden Beispiel zu tun. Grundsätzlich besteht die Idee darin, allgemeine und / oder kontextspezifische Codestücke zu extrahieren, um die Modelle zu bereinigen und zu vermeiden, dass sie zu fett und unordentlich werden.
Als Beispiel werde ich ein bekanntes Muster einfügen, das taggable Muster:
# 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
Wenn Sie dem Produktbeispiel folgen, können Sie Taggable zu jeder gewünschten Klasse hinzufügen und deren Funktionalität freigeben.
Dies wird von DHH ziemlich gut erklärt :
In Rails 4 werden wir Programmierer einladen, Bedenken mit den Standardverzeichnissen app / models / Concern und app / controller / Concern zu verwenden, die automatisch Teil des Ladepfads sind. Zusammen mit dem ActiveSupport :: Concern-Wrapper reicht diese Unterstützung gerade aus, um diesen leichten Factoring-Mechanismus zum Leuchten zu bringen.
Ich habe über die Verwendung von Modellproblemen gelesen, um Fettmodelle zu häuten und Ihre Modellcodes auszutrocknen. Hier ist eine Erklärung mit Beispielen:
1) Trocknen von Modellcodes
Betrachten Sie ein Artikelmodell, ein Ereignismodell und ein Kommentarmodell. Ein Artikel oder eine Veranstaltung hat viele Kommentare. Ein Kommentar gehört entweder zum Artikel oder zum Ereignis.
Traditionell sehen die Modelle folgendermaßen aus:
Kommentar Modell:
Artikelmodell:
Ereignismodell
Wie wir feststellen können, gibt es sowohl für Event als auch für Article einen wichtigen Code. Mit Bedenken können wir diesen gemeinsamen Code in einem separaten Modul Commentable extrahieren.
Erstellen Sie dazu eine commentable.rb-Datei in App / Models / Concerns.
Und jetzt sehen Ihre Modelle so aus:
Kommentar Modell:
Artikelmodell:
Ereignismodell:
2) Hautfettende Fettmodelle.
Betrachten Sie ein Ereignismodell. Eine Veranstaltung hat viele Teilnehmer und Kommentare.
In der Regel sieht das Ereignismodell folgendermaßen aus
Modelle mit vielen Assoziationen und anderen Tendenzen neigen dazu, immer mehr Code anzusammeln und nicht mehr zu verwalten. Bedenken bieten eine Möglichkeit, Fettmodule zu häuten, wodurch sie modularer und verständlicher werden.
Das obige Modell kann mithilfe der folgenden Bedenken überarbeitet werden: Erstellen Sie eine
attendable.rb
undcommentable.rb
-Datei im Ordner app / models / ca. / eventattendable.rb
commentable.rb
Und jetzt, wo Sie Bedenken verwenden, reduziert sich Ihr Ereignismodell auf
* Bei der Verwendung von Bedenken ist es ratsam, sich für eine domänenbasierte Gruppierung anstatt für eine technische Gruppierung zu entscheiden. Domainbasierte Gruppierung ist wie "Kommentierbar", "Fotofähig", "Teilnahmefähig". Technische Gruppierung bedeutet "ValidationMethods", "FinderMethods" usw.
quelle
def self.my_class_method
), Instanzmethoden sowie Methodenaufrufe und Direktiven im Klassenbereich. Keine Notwendigkeit fürmodule ClassMethods
add_item
, sind Sie fertig. Ich erinnere mich, dass ich dachte, Rails sei kaputt, als einige Validatoren aufhörten zu arbeiten, aber jemand hatteany?
ein Problem gelöst. Ich schlage eine andere Lösung vor: Verwenden Sie das Anliegen wie eine Schnittstelle in einer anderen Sprache. Anstatt die Funktionalität zu definieren, wird der Verweis auf eine separate Klasseninstanz definiert, die diese Funktionalität verarbeitet. Dann haben Sie kleinere, ordentlichere Klassen, die eines tun ...Es ist erwähnenswert, dass die Verwendung von Bedenken von vielen als schlechte Idee angesehen wird.
Einige Gründe:
include
Methoden, es gibt ein ganzes Abhängigkeitsbehandlungssystem - viel zu viel Komplexität für etwas, das trivial gut ist, altes Ruby-Mixin-Muster.Bedenken sind eine einfache Möglichkeit, sich ins Bein zu schießen. Seien Sie vorsichtig mit ihnen.
quelle
Dieser Beitrag hat mir geholfen, Bedenken zu verstehen.
quelle
Ich hatte das Gefühl, dass die meisten Beispiele hier
module
eher die Kraft als denActiveSupport::Concern
Mehrwert demonstrierenmodule
.Beispiel 1: Lesbarere Module.
Also ohne Bedenken, wie ein typischer sein
module
wird.Nach dem Refactoring mit
ActiveSupport::Concern
.Sie sehen, dass Instanzmethoden, Klassenmethoden und eingeschlossene Blöcke weniger chaotisch sind. Bedenken werden sie angemessen für Sie injizieren. Das ist ein Vorteil der Verwendung
ActiveSupport::Concern
.Beispiel 2: Behandeln Sie Modulabhängigkeiten ordnungsgemäß.
In diesem Beispiel
Bar
ist das Modul, dasHost
wirklich benötigt. Aber daBar
muss die Abhängigkeit vonFoo
derHost
Klasse seininclude Foo
(aber warten, warumHost
will man das wissenFoo
? Kann man das vermeiden?).So
Bar
fügt Abhängigkeit überall geht es. Und die Reihenfolge der Aufnahme zählt auch hier. Dies erhöht die Komplexität / Abhängigkeit der riesigen Codebasis erheblich.Nach dem Refactoring mit
ActiveSupport::Concern
Jetzt sieht es einfach aus.
Wenn Sie überlegen, warum können wir keine
Foo
Abhängigkeit imBar
Modul selbst hinzufügen ? Das wird nicht funktionieren, damethod_injected_by_foo_to_host_klass
es in eine Klasse eingefügt werden muss, dieBar
nicht auf demBar
Modul selbst enthalten ist.Quelle: Rails ActiveSupport :: Concern
quelle
In Bedenken machen Sie die Datei filename.rb
Zum Beispiel möchte ich in meiner Anwendung, in der das Attribut create_by existiert, den Wert um 1 und 0 für update_by aktualisieren
Wenn Sie Argumente in Aktion übergeben möchten
Danach nehmen Sie Folgendes in Ihr Modell auf:
quelle