Magento 2 Experten — Hyvä Theme, Tailwind CSS & SEO aus einer Hand ›

Zusammenfassung Attribute-Block: Checkliste für eigene Attribute

Zusammenfassung Attribute-Block: Checkliste für eigene Attribute

~6 Min. Lesezeit Zuletzt aktualisiert am 9. August 2026

Neun Kapitel, fünf Attribute, drei grundverschiedene Speichertechniken, ein Backend Model und ein Resolver-Service für Konsistenz über Attributgrenzen hinweg - dieses Kapitel fasst Block 3 (Kapitel 19-27) als Nachschlagewerk zusammen, bevor Block 4 in Kapitel 29 mit Observern und Cron das nächste Thema beginnt. Gedacht zum Zurückkommen, nicht zum einmaligen Durchlesen.

Die fünf Attribute im Rückblick

  • Product - loyalty_points_multiplier (decimal, Default 1.0000), angelegt per EavSetup in InstallProductLoyaltyAttribute (Kapitel 19), Scope zunächst global, ab Kapitel 25 per UpdateProductLoyaltyAttributeScope auf Website umgestellt.
  • Category - loyalty_bonus_category (decimal, Default 0), InstallCategoryLoyaltyAttribute (Kapitel 20), direkt mit Website-Scope angelegt.
  • Customer - loyalty_points_balance (int) und loyalty_tier (varchar, Dropdown über LoyaltyTier-Source-Model), InstallCustomerLoyaltyAttributes (Kapitel 21), loyalty_tier seit Kapitel 26 über LoyaltyTierBackend automatisch berechnet.
  • Company - loyalty_tier_override (varchar, dasselbe LoyaltyTier-Source-Model wiederverwendet), über Extension Attribute (etc/extension_attributes.xml) plus AddLoyaltyTierOverridePlugin (Kapitel 22), weil company keine EAV-Entität ist.
  • Sales - loyalty_points_earned auf sales_order und sales_order_item, per SalesSetup::addAttribute() in InstallSalesLoyaltyAttributes (Kapitel 23) als echte Spalte angelegt.

Drei Techniken, eine Entscheidung

  1. Echte EAV-Entität (Product, Category, Customer, die eigene Reward-Entity aus Block 2): EavSetup::addAttribute()/updateAttribute(), Werte landen in den *_varchar/*_int/*_decimal/*_text/*_datetime-Tabellen.
  2. Flache Sales-Entität mit eigenem Setup-Helfer (Order, Order Item, Invoice, Credit Memo): SalesSetup::addAttribute() - sieht aus wie EAV, legt aber eine echte Spalte an (Kapitel 23).
  3. Flache Entität ohne eigenen Setup-Helfer (Company und die meisten Fremd- oder Custom-Entitäten ohne EAV): eigene Spalte per db_schema.xml auf der Fremd-Tabelle plus extension_attributes.xml plus Plugin, weil das feste Interface (CompanyInterface) keine eigenen Getter/Setter erlaubt (Kapitel 22).

Checkliste für jedes neue Attribut

  1. Ist die Ziel-Entität eine echte EAV-Entität, eine Sales-Entität oder flach ohne eigenen Setup-Helfer? Bestimmt sofort, welche der drei Techniken oben zum Einsatz kommt.
  2. Scope bewusst wählen (SCOPE_GLOBAL/SCOPE_WEBSITE/SCOPE_STORE), nicht einfach den EAV-Default übernehmen (Kapitel 25) - bei flachen Entitäten entfällt diese Frage ohnehin.
  3. user_defined, system => false, visible und required korrekt setzen - ein vergessenes system => false macht ein Kundenattribut im Admin unsichtbar bearbeitbar oder unlöschbar (Kapitel 21).
  4. Braucht das Attribut ein Dropdown? Ein wiederverwendbares Source Model unter einem entitätsneutralen Namespace ablegen (Kapitel 24), sonst reicht die kurze 'option'-Array-Form direkt im addAttribute()-Aufruf.
  5. Muss der Wert beim Speichern automatisch berechnet oder validiert werden? Ein Backend Model registrieren - aber die Kontravarianz-Falle bei ungetypten Parametern aus Kapitel 26 im Kopf behalten.
  6. Speisen mehrere Attribute oder mehrere Werte desselben Attributs (Mehrfachkategorien!) gemeinsam eine Berechnung? Die Auflösungsregel in einem eigenen, benannten Resolver-Service dokumentieren statt sie in Observer oder Controller zu verstreuen (Kapitel 27).
  7. bin/magento setup:upgrade und den passenden Reindex nicht vergessen (catalog_product_attribute für Produkt-/Kategorieattribute, customer_grid für Kundenattribute) - bei Sales-Attributen zusätzlich prüfen, ob sales_order_grid separat synchronisiert werden muss (Kapitel 23).
  8. Alle Admin-Labels mit __() wrappen, sonst greift eine spätere i18n-CSV-Übersetzung (Block 11) nicht (Kapitel 24).
  9. module.xml-sequence um das jeweilige Fremdmodul ergänzen (Magento_Eav, Magento_Customer, Magento_Sales, Magento_Company, Magento_Catalog - je nachdem, welche Entität betroffen ist).
  10. Ein bereits produktiv genutztes Attribut ändern? updateAttribute() statt Löschen und Neuanlegen - bestehende Werte bleiben unter store_id = 0 als Fallback erhalten (Kapitel 25, 26).

Häufige Fallstricke auf einen Blick

  • addFieldToFilter() mit einem int-Wert immer als ['eq' => $value] - Projekt-Konvention aus CLAUDE.md, gilt genauso für jede Collection auf diesen Attributen.
  • updateAttribute() erwartet den neuen Wert direkt als vierten Parameter, kein assoziatives Array wie bei addAttribute() (Kapitel 25).
  • Entity-Type-Codes wie 'order'/'order_item' bei SalesSetup sind String-Literale ohne Autovervollständigung - ein Tippfehler scheitert erst tief im Framework (Kapitel 23).
  • extension_attributes.xml allein füllt ein Feld nicht automatisch - ohne Plugin bleibt der Wert leer (Kapitel 22).
  • $product->getCategoryId() (Singular) ist Request-Kontext, kein gespeicherter Wert - für Berechnungen immer getCategoryIds() (Plural) nutzen (Kapitel 27).
  • Ein Backend Model darf seinen $object-Parameter nicht typisieren, weil AbstractBackend selbst keinen Typ deklariert - PHP verbietet das nachträgliche Verschärfen eines Parametertyps (Kapitel 26).

Tipp: Diese Checkliste lohnt sich als Lesezeichen für jedes zukünftige eigene Modul, das Attribute an bestehenden Entitäten ergänzt - unabhängig davon, ob es sich um ein Treueprogramm oder ein völlig anderes Feature handelt. Die Technik-Entscheidung (EAV vs. Sales-Setup vs. Extension-Attribute-plus-Plugin) ist der wichtigste erste Schritt, weil sie alles Folgende festlegt.

Block 4 beginnt in Kapitel 29 mit dem Event-System: Genau hier - im Observer AwardPointsOnOrderPlaced aus Kapitel 30 - kommen PointsCalculator, CategoryBonusResolver und die automatisch aktualisierten Attribute aus diesem Block zum ersten Mal alle gemeinsam in einem einzigen Ablauf zusammen: der tatsächlichen Punktevergabe bei Bestellabschluss.