Snippets

Create an account or login to be able to add, comment and rate snippets.

Navigation

Simulating an enum column type in the model

As enum is a MySQL specific type, you cannot have a column of type enum in your schema.yml (which is database-independent). One solution to simulate it is to create another table to store the different possible values. But the Model class offer an alternative solution that is probably more elegant.

Imagine you have a status column in you article table you want to be an enumerated list with values like (open, closed). Simply declare the status column as integer and then modify the model as follows:

In ArticlePeer.php:

class ArticlePeer...
{
   static protected $STATUS_INTEGERS = array('open', 'closed');
   static protected $STATUS_VALUES = null;
 
   static public function getStatusFromIndex($index)
   {
     return self::$STATUS_INTEGERS[$index];
   }
 
   static public function getStatusFromValue($value)
   {
     if (!self::$STATUS_VALUES)
     {
       self::STATUS_VALUES = array_flip(self::$STATUS_INTEGERS);
     }
 
     $values = strtolower($value);
 
     if (!isset(self::STATUS_VALUES[$value])
     {
       throw new PropelException(sprintf('Status cannot take "%s" as a value', $value));
     }
 
     return self::STATUS_VALUES[strtolower($value)];
   }
}

In Article.php:

class Article
{
   public function setStatusName($value)
   {
     $this->setStatus(ArticlePeer::getStatusFromValue($value));
   }
 
   public function getStatusName()
   {
     return ArticlePeer::getStatusFromIndex($this->getStatus());
   }
}

(Original tip from Fabien)

by Francois Zaninotto on 2006-10-27, tagged enum  getter  model  mysql  setter 

Comments on this snippet

gravatar icon
#1 Luciano Andrade on 2006-11-21 at 04:30

In ArticlePeer.php: self::STATUS_VALUES shuld say self::$STATUS_VALUES self::STATUS_INTEGER shuld say self::$STATUS_INTEGER

and the variable values of the method getStatusFromValue is never used.

the if need and extra ) at the en of the line

In Article.php if you don't want to add a new field (StatusName) you could <pre> class Article { public function setStatus($value) { paret::setStatus(ArticlePeer::getStatusFromValue($value)); }

public function getStatus() { return ArticlePeer::getStatusFromIndex($this->getStatus()); } }

</pre>

gravatar icon
#2 Satya Prakash on 2007-12-20 at 12:44

i did as said in this article. Now i want to use it.

i am trying to use it in admin/backend. I am trying to add dropdown list for this field instead of input field. This generator.yml is not giving any error: generator: class: sfPropelAdminGenerator param: model_class: Category theme: default

fields:
  category:       { name: Category }
  status_name:    { name: Status, type: select_tag }
 
list:
  fields:
    title:        { name: Title }
    status_name:       { name: Status, type: select_tag}
 
edit:
  display:
    &quot;Create/Edit Category&quot;:         [category, status]
  fields:
    status_name:    { name: Status, type: select_tag}
 

Module is right.

gravatar icon
#3 yousef nabulsi on 2007-12-29 at 02:57

This is a nice solution but the enum vales must be not be retrieved as fixed values (ie suppose i want to add or remove an enum value in future ), How could i do that without modifying the php code later .

gravatar icon
#4 Chris Prior on 2008-01-11 at 11:57

@yousef: Use a 1:n table in the schema then. Like document_type for the base table document with document.document_type_id

gravatar icon
#5 juan martin on 2008-05-29 at 08:45

I have one failed in line 18 of ArticlePeer.php

Warning: Illegal offset type in /srv/www/libros/lib/model/LibrosPeer.php on line 18

My generator.yml is =>

edit: fields: status: { name: Status, type: select_tag, params: peer_method=getStatusFromIndex related_class=Libros }

I need help is urgent i have proyect wednesday 4 - jun -2008

Thanks

You need to create an account or log in to post a comment or rate this snippet.