· 4 min read
Die Pluralisierungsmuster von Rails verstehen
Lösung
Es gibt drei Stellen, an denen Rails standardmäßig Pluralisierungskonventionen verwendet:
Namen von Datenbanktabellen: Plural
Die Namen von Datenbanktabellen werden im (englischen) Plural erwartet. So sollte eine Tabelle mit Mitarbeiterdaten (engl. employee) Employees genannt werden.
Namen von Modellklassen: Singular
Die Namen von Modellklassen liegen als Singular der Datenbanktabelle vor, die sie modellieren. So wird beispielsweise ein Employee-Modell basierend auf einer Tabelle namens employees aufgebaut.
Namen von Controller-Klassen: Plural
Die Namen von Controller-Klassen werden pluralisiert, z.B. EmployeesController oder AccountsController.
Sich mit diesen drei Konventionen vertraut zu machen ist ein großer Schritt auf dem Weg, sich bei Rails heimisch zu fühlen. Die Idee hinter der Pluralisierung ist, Ihren Code leserlicher und transparenter zu machen. Ein gutes Beispiel für die Lesbarkeit von Rails-Code bildet die Einrichtung einer 1-zu-M-Beziehung zwischen Kapiteln und Rezepten:
app/models/chapter.rb:
class Chapter < ActiveRecord::Base
has_many :recipes
end
Dieser Code sagt: »Ein Kapitel (Chapter) hat viele Rezepte (recipes)«. Sie können sehen, dass das die tieferliegende Beziehung zwischen Kapiteln und Rezepten beschreibt. Und es ist auch für Nicht-Programmierer und Kunden verständlich.
Es gibt andere Stellen, an denen Rails die Pluralisierung nutzt, darunter View-Verzeichnisnamen und Dateinamen funktionaler Tests, Unit-Tests und Test-Fixtures.
Eine der besten Möglichkeiten, sich an die Pluralisierung zu gewöhnen, besteht darin, mit den Rails-Generatoren zu experimentieren und die Option —pretend (oder einfach -p) zu verwenden, wenn man mit script/generate Scaffolding, Controller oder Modelle generiert.
$ ruby script/generate scaffold -p recipe
exists app/controllers/
exists app/helpers/
create app/views/recipes
exists test/functional/
dependency model
exists app/models/
exists test/unit/
exists test/fixtures/
create app/models/recipe.rb
create test/unit/recipe_test.rb
create test/fixtures/recipes.yml
create app/views/recipes/_form.rhtml
create app/views/recipes/list.rhtml
create app/views/recipes/show.rhtml
create app/views/recipes/new.rhtml
create app/views/recipes/edit.rhtml
create app/controllers/recipes_controller.rb
create test/functional/recipes_controller_test.rb
create app/helpers/recipes_helper.rb
create app/views/layouts/recipes.rhtml
create public/stylesheets/scaffold.cs
Rails wirft (basierend auf dem von Ihnen übergebenen String) alle Dateien aus, die es generieren würde, ohne diese tatsächlich anzulegen. Sie können das Flag —pretend einsetzen, um zu sehen, ob und wann Rails verschiedene Wörter pluralisiert. Schließlich sei noch auf Geoffrey Grosenbach verwiesen, der ein Online-Tool namens »The Pluralizer« gepostet hat, das alle Rails-Pluralisierungskonventionen für ein gegebenes Wort zeigt. Sie finden das Tool unter http://nubyonrails.com/tools/pluralize.
Diskussion
Die Pluralisierung in Rails ist oft das Thema heißer Debatten, insbesondere unter Skeptikern, die eine Debatte vom Zaun brechen wollen. Die Pluralisierung ist nur eine Konvention in einer Reihe von Konventionen, die Rails verwendet. Es versucht damit einen Großteil der Konfiguration zu elimieren, die bei Web-Entwicklungs-Frameworks normalerweise nötig sind.
Letztendlich ist die Pluralisierung nur eine Konvention. Es steht Ihnen immer frei, sie global zu deaktivieren oder in bestimmten Fällen zu überschreiben. Sie deaktivieren sie mit der folgenden Zeile in der Konfigurationsdatei environment.rb:
config/environment.rb:
ActiveRecord::Base.pluralize_table_names = false
Ein Problem mit der Pluralisierung besteht darin, dass nicht alle Wörter die richtige Beugung erfahren. Die Klasse, die darüber entscheidet, wie Wörter pluralisiert werden, heißt Inflections. Diese Klasse definiert Methoden, die in Rubys String-Klasse eingebunden werden. Diese Methoden werden in Rails allen String-Objekten zur Verfügung gestellt. Sie können mit diesen Methoden, namentlich mit pluralize, direkt in der Rails-Konsole experimentieren. Hier ein Beispiel:
$ ruby script/console
Loading development environment.
>> "account".pluralize
=> "accounts"
>> "people".pluralize
=> "peoples"
Viele der verschiedenen Grenzfälle der englischen Pluralisierung sind in einer Datei namens inflections.rb innerhalb des ActiveSupport-gem-Verzeichnisses enthalten. Hier eine gekürzte Version dieser Datei:
activesupport-1.3.1/lib/active_support/inflections.rb:
Inflector.inflections do |inflect|
inflect.plural(/$/, 's')
inflect.plural(/s$/i, 's')
inflect.plural(/(ax|test)is$/i, '1es')
...
inflect.singular(/s$/i, '')
inflect.singular(/(n)ews$/i, '1ews')
inflect.singular(/([ti])a$/i, '1um')
...
inflect.irregular('person', 'people')
inflect.irregular('man', 'men')
inflect.irregular('child', 'children')
...
inflect.uncountable(%w(equipment information rice money species series fish sheep))
end
Sie werden letztlich eine bestimmte Pluralisierungsregel finden, die in dieser Datei fehlt. Nehmen wir zum Beispiel an, Sie hätten eine Tabelle mit foo-Datensätzen (die jeweils einen Tipp enthalten, mit denen Ruby-Neulinge zu Meistern werden). In diesem Fall ist der Plural von foo einfach foo, was die pluralize-Methode aber nicht so sieht:
$ ruby script/console
>> "foo".pluralize
=> "foos"
Rails bezeichnet Wörter, die im Plural und im Singular identisch sind, als »unzählbar« (uncountable). Um das Wort foo in eine Liste aller unzählbaren Wörter aufzunehmen, hängen Sie Folgendes an das Ende von environment.rb an:
config/environment.rb:
...
Inflector.inflections do |inflect|
inflect.uncountable "foo"
end
Laden Sie script/console neu, pluralisieren Sie foo erneut, und Sie werden feststellen, dass Ihre neue Flexionsregel korrekt angewandt wurde.
$ ruby script/console
>> "foo".pluralize
=> "foo"
Weitere Flexionsregeln können dem Block hinzugefügt werden, der an Inflector.inflections übergeben wird. Hier einige Beispiele:
Inflector.inflections do |inflect|
inflect.plural /^(ox)$/i, '12en'
inflect.singular /^(ox)en/i, '1'
inflect.irregular 'octopus', 'octopi'
inflect.uncountable "equipment"
end
Diese Regeln werden vor den in inflections.rb definierten Regeln angewandt. Daher können Sie von diesem Framework definierte, vorhandene Regeln überschreiben.
Dieses Rezept stammt aus dem Rails Kochbuch, veröffentlicht beim O’Reilly Verlag