【问题标题】:Yii2 activerecord custom attributeYii2 activerecord 自定义属性
【发布时间】:2015-07-24 10:01:58
【问题描述】:

我正在尝试在扩展 db\activerecord 的模型类中使用自定义属性。

我尝试过声明public $categories = [],然后通过$model->categories = [1,2,3] 直接为其赋值,或者在我的模型类public function setCategories($ids) {... 中使用setter 方法,然后再次通过$model->categories = [1,2,3] 进行赋值。

我也尝试使用$model->setAttribute('categories', [1,2,3]) 更新属性。

在所有情况下,$model->categories 都不会被填充。

我的最终目标是为模型分配类别,然后使用afterSave()beforeSave() 更新数据库关系/表

可以这样做还是应该从db\model 扩展我的模型类?如果这样做,我会失去什么功能?

编辑 我可能误报了我的问题。

我有一个表单,用户可以在其中选择特定模型的类别(即“产品”)。所有类别都是预先存在的,产品通过具有一对多关系(一个产品有多个类别)的联结表 product_category('product_id', 'category_id') 分配给类别。

现在在处理视图的控制器中,我收到一个类别 ID 列表,我想将它们分配给一个属性,以便我可以处理它们,即删除或添加(通过link())product_category 中的条目特定产品的表格。

【问题讨论】:

    标签: php activerecord yii2


    【解决方案1】:
    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
       }
    }
    

    【讨论】:

      【解决方案2】:

      在我看来,您是在手动尝试在表之间建立关系? 为什么不使用内置功能并为您服务?

      对于这个(多对多),您需要一个链接 activerecord 或表来指示哪些模型链接到哪些类别(我在这里假设您有一个称为 ModelCategoryActiveRecord 并且有一个 @ 987654325@ 和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');
      }
      

      (您也可以使用viaTable() 代替via() 并避免使用额外的方法,这是您的选择。)

      这意味着您可以像这样访问它们:

      $product->categories  
      

      (总是对关系使用神奇的功能,实际执行数据库查询的是 __get() 函数)。

      对于分配关系,没有自动方法。 Yii 有一些辅助功能:

      $category = new Category();
      // Assign attributes
      $category->save();
      
      $product = new Product();
      // Assign attributes
      $product->save();
      
      $product->link('categories', $category);
      

      查看link-function 了解更多详情。 显然也有其他方法,但这取决于您的需求。

      根据您的额外信息:

      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);
         }
      }
      

      未经测试,但这应该让您了解如何解决这个问题。

      【讨论】:

      • 正如您提到的,我已经正确设置了关系,并且可以正确获取模型的类别。我现在要做的是在我的控制器中设置/保存模型的类别。从我在这里看到的github.com/yiisoft/yii2/issues/2397 来看,我正在尝试做的事情应该有效。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多