Empfehlungen: Erweiterte Suche

Static Enums or "The Power of Semihardcoded Attributes"

Anleitungen und Quellcode-Auszüge die den Start vereinfachen sollen.

Static Enums or "The Power of Semihardcoded Attributes"

Beitragvon euromark » Fr 19. Mär 2010, 14:06

Ich werd mal aufzeigen, wie man extrem effizient - und zugleich sehr einfach erweiterbar - attribute speichern kann, für die manche eine zusätzliche völlig überflüssige Relation anlegen.
Oft sind solche Eigenschaften/Attribute unter dem typ "enums" zusammengefasst - und werden von cake ja nicht nativ unterstützt.

So gehts (auf englisch ab hier):

a) Add tinyint(2) unsigned field called for example "status" (singular)
"Tinyint 2 unsigned" covers 0...255 - which should always be enough for enums. if you need more, you SHOULD make an extra relation as real table. dont use tinyint(1) as cake interprets this as a toggle field, which we dont want!

b) Put this in your app_model.php:
Code: Alles auswählen
  /**
   * static enums
   * 2009-11-05 ms
   */

  function enum($value, $options, $default = '') {
      if ($value !== null) {
        if (array_key_exists($value, $options)) {
            return $options[$value];
        }
        return '';
    }
    return $options;
  }


c) put something like this in any model where you want to use enums:
Code: Alles auswählen
    /**
     * static enum: Model::function()
     * @access static
     * 2009-09-02 ms
     */

    function statuses($value = null) {
        $options = array(
            self::STATUS_NEW => __('statusNew',true),
            self::STATUS_UNREAD => __('statusUnread',true),
            self::STATUS_READ => __('statusRead',true),
            self::STATUS_ANSWERED => __('statusAnswered',true),
            self::STATUS_DELETED => __('statusDeleted',true),
        );
    return parent::enum($value, $options);
    }

    const STATUS_NEW = 0; # causes sound, then marks itself as "unread"
    const STATUS_UNREAD = 1;
    const STATUS_READ = 2;
    const STATUS_ANSWERED = 4;
    const STATUS_DELETED = 5;
    // add more - order them as you like


d) use them in your controller logic, model functions, view forms, ...:

Code: Alles auswählen
//view form
...
echo $this->Form->input('status', array('options'=>Notification::statuses()));

Code: Alles auswählen
//controller action
...
if ($this->data['Notification']['status'] == Notification::STATUS_READ)) {...}

Code: Alles auswählen
//controller logic on find
...
$options = array('conditions'=>array('Notification.user_id'=>$uid, 'Notification.status <='=>Notification::STATUS_UNREAD));
$notifications = $this->Notification->find('all', $options);

Code: Alles auswählen
//view index/view
...
<?php echo h($notification['Notification']['title']);?>
<?php echo Notification::statuses($notification['Notification']['status']); // returns translated text ?>

=> NOTE: example with "statuses", could also be priorities, gender, types, categories, ... etc
anything that is not often changed or extended

Thats it!

Conclusion: fast and easy to extend in the future if neccessary
it also saves a lot of overhead by using (tiny)ints instead of strings
AND it does not need any additional table joins! which makes it even more performant

futher advantages
- reorder them by just changing the order of the array values in the model
- auto-translated right away (i18n without any translation tables - very fast)

what you cant do:
- sort by the value of the keys (only by keys): small, medium, low => no sorting by their name ASC/DESC, only by key ASC/DESC


Final tipps:
if you use them in an index view many times repeatedly, if would make sense to write them into an array before using them. otherwise the translation will be transformed every time. caching would also work!

validation/emptyFields: use 'empty' attribute in form helper options array for default "blank" with either 'empty'=>array(0=>'xyz') to allow 0 values or 'empty'=>'xyz' to require one value (combined with validation rule "numeric")
euromark
 
Beiträge: 618
Registriert: Fr 27. Jun 2008, 22:17
Wohnort: München
CakePHP-Version: 2.1
OS: Windows

Re: Static Enums or "The Power of Semihardcoded Attributes"

Beitragvon havanna » Sa 20. Mär 2010, 14:56

Hallo Mark,

vielen Dank für den Tipp und die ausführliche Beschreibung. Ich habe das gleich einmal angewendet.

In meiner Anwendung kenne ich drei Geschäftspartnertypen: "Person, Unternehmen, Gruppe". Das spart eine Tabelle.

Ciao Thomas
Benutzeravatar
havanna
 
Beiträge: 191
Registriert: Mi 15. Okt 2008, 23:12
Wohnort: Bodman-Ludwigshafen
CakePHP-Version: 1.2.x
OS: WIN

Re: Static Enums or "The Power of Semihardcoded Attributes"

Beitragvon euromark » Sa 20. Mär 2010, 16:06

na, siehste :)
euromark
 
Beiträge: 618
Registriert: Fr 27. Jun 2008, 22:17
Wohnort: München
CakePHP-Version: 2.1
OS: Windows

Re: Static Enums or "The Power of Semihardcoded Attributes"

Beitragvon euromark » Mo 29. Aug 2011, 10:58

für alle die es interessiert, ich hab es geschafft, meine enums nun auch direkt in die back templates zu integrieren
ein tinyint(2) status feld würde so z.b. direkt beim backen alle notwendigen formularfelder mit inhalt erstellen, bzw in index/view direkt den text dazu.

schauts euch im originalbeitrag an:
http://www.dereuromark.de/2010/06/24/static-enums-or-semihardcoded-attributes/
euromark
 
Beiträge: 618
Registriert: Fr 27. Jun 2008, 22:17
Wohnort: München
CakePHP-Version: 2.1
OS: Windows


Zurück zu Tutorials und Snippets

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast