Herramientas de usuario

Herramientas del sitio


cursos:yii2:clases:activerecord:json

Campos JSON

En algunas ocasiones es práctico almacenar información en campos de una tabla en formato Json, que evita tener que crear tablas auxiliares que pueden complicar el mantenimiento y no aportan rendimiento. Por ejemplo: si tenemos datos adicionales de una ficha de usuario que son definibles (mediante un formulario definible tipo Google Forms) y diferentes según el tipo de usuario, o asignar un conjunto de etiquetas a un producto , podemos utilizar un campo tipo varchar largo o TEXT para almacenar toda esa información . La forma de manejar todo esto con Yii es la siguiente:

Imaginemos que tenemos un atributo llamado “tags”, que debe guardar una lista de etiquetas de un producto

En el modelo, definimos los métodos afterFind y beforeSave, que se ejecutan cuando se lee un registro de la base de datos y antes de guardar el registro:

public function afterFind() {
  $this->datos=json_decode($this->tags,true); //Los convertimos desde Json a array de datos
  return parent:afterFind();
}
public function beforeSave($insert) {
  $this->datos=json_encode($this->tags); //Los convertimos a Json
  return parent:beforeSave($insert);
}

Desde el controlador o desde la vista, $model→tags será un array de etiquetas. En la vista por ejemplo:

   GridView(
   ...
   ['attribute'=>'tags',
     'value'=>function($data){
        $ret='';
        foreach($data->tags as $tag)
           $ret.="<span class='badge badge-success'>$tag</span> ";
        return $ret;
     }
   ]

En el formulario, se debe utilizar un name de la forma “Productos[tags][]”. Si utilizamos un dropDown con la opción 'multiple', Yii le asignará ese nombre automáticamente:

    echo $form->field($model, 'tags')->dropDownList(Productos::$tagsOptions,['multiple'=>true]);

También podemos utilizar una lista de campos TextField que permita añadir y eliminar etiquetas, mediante JavaScript.

Cuando se envíe el formulario, se asignarán las etiquetas como un array, y en beforeSave() se convertirán a JSON del estilo:

  ["Estilo de vida","Salud","Alimentación"]

Los campos Json pueden almacenar cualquier estructura de datos multinivel: objetos, array de objetos, arrays de arrays…

ATENCIÓN: No deben utilizarse estsos campos para almacenar “id” que referencien a otras tablas, ya que hpodría haber problemas de integridad de datos: si se borra el registro referenciado , Mysql no puede eliminar ni hacer nada con este registro que lo tiene asociado.