php - una - Atributo personalizado Yii2 activerecord
yii2 create model (2)
db/activerecord
usar un atributo personalizado en una clase de modelo que extiende db/activerecord
.
Intenté declarar public $categories = []
y luego asignarle valores directamente a través de $model->categories = [1,2,3]
o usar un método setter en mi clase class public function setCategories($ids) {...
y luego asignando de nuevo a través de $model->categories = [1,2,3]
.
También intenté actualizar el atributo con $model->setAttribute(''categories'', [1,2,3])
.
En todos los casos, $model->categories
no está poblado.
Mi objetivo final es asignar categorías a un modelo y luego actualizar las tablas / relación db usando afterSave()
y beforeSave()
¿Se puede hacer esto o debería extender mi clase de modelo desde db/model
? Si lo hago, ¿qué funcionalidad perderé?
Editar Podría haber malinterpretado mi problema.
Tengo un formulario donde un usuario puede seleccionar categorías para un modelo específico (es decir, "Producto"). Todas las categorías son preexistentes y los productos se asignan a categorías a través de una tabla de unión product_category (''product_id'', ''category_id'') con una relación de uno a varios (un producto tiene muchas categorías).
Ahora, en el controlador que maneja la vista, recibo una lista de identificadores de categoría y deseo asignarlos a un atributo para que pueda procesarlos, es decir, eliminar o agregar (a través de las entradas de link()
) en la tabla de categoría de producto para el producto específico.
Me parece que estás tratando de hacer relaciones entre tablas de forma manual? ¿Por qué no utilizar la funcionalidad incorporada y tenerlo cuidado?
Para esto (de muchos a muchos) necesita un enlace activerecord o tabla que indique qué modelos enlazan con qué categorías (supongo que tiene un ActiveRecord
que se llama ModelCategory
y tiene un model_id
y un category_id
:
public function getProductCategories()
{
return $this->hasMany(ProductCategory::className(), [''product_id'' => ''id'']);
}
public function getCategories()
{
return $this->hasMany(Category::className(), [''id'' => ''category_id''])
->via(''productCategories'');
}
(También puede usar viaTable()
lugar de via()
y evitar un método adicional, esa es su elección).
Esto significa que puede acceder a ellos de la siguiente manera:
$product->categories
(Siempre use la funcionalidad mágica para las relaciones, es la función __get () la que realmente hace la consulta de la base de datos).
Para asignar relaciones no hay un método automático. Yii tiene algunas funciones de asistencia para esto:
$category = new Category();
// Assign attributes
$category->save();
$product = new Product();
// Assign attributes
$product->save();
$product->link(''categories'', $category);
Consulte la función de link
para más detalles. Obviamente, hay otras formas también, pero depende de sus necesidades.
Según su información adicional:
public function actionAssignCategories($product, $categories)
{
$product = Product::findOne($product);
$existingCategories = /yii/base/ArrayHelper::getColumn($product->categories, ''category_id'');
$removeCategories = array_diff($existingCategories, $categories);
$addCategories = array_diff($categories, $existingCategories);
foreach ($addCategories as $category) {
$category = Category::findOne($category);
$product->link(''categories'', $category);
}
foreach ($removeCategories as $category) {
$category = Category::findOne($category);
$product->unlink(''categories'', $category);
}
}
No probado, pero eso debería darte una idea sobre cómo abordar esto.
class ClassName extends /yii/db/ActiveRecord
{
public $addition; //what attribute you want
/* your code */
public function fields()
{
$fields = parent::fields();
$fields[] = ''addition''; //the value must be the same as the new attribute
/* your code */
$this->addition = ''done''
return $fields
}
}