简体   繁体   English

如何将 Yii 2 中的属性链接到另一个模型的字段?

[英]How to link attribute in Yii 2 to another model's field?

I have Products model and ProductProperties via hasOne relation:我通过 hasOne 关系拥有 Products 模型和 ProductProperties:

class Product extends ActiveRecord
{
...
public function getProductProperties()
 {
     return $this->hasOne(ProductProperties::class, ['product_id' => 'id']);
 } 
...
}

I had price attribute in Products and I want to remove it (including column in database) and to link it to price attribute of ProductProperties model.我在 Products 中有价格属性,我想删除它(包括数据库中的列)并将其链接到 ProductProperties 模型的价格属性。 Is it possible and how can I do that?有可能吗?我该怎么做? First I tried to override attributes method like this:首先,我尝试像这样覆盖属性方法:

    public function fields()
    {
       return [
           'price' => function () {
             return ProductProperties::find(['product_id' => $this->id])->price;
           }
       ]
...

but I'm not sure if I can assign values using arrow method.但我不确定是否可以使用箭头方法分配值。 Besides, fields() method uses $this->price before it returns anything:此外,fields() 方法在返回任何内容之前使用$this->price

public function fields()
    {
    if ($this->price){*some manipulations with price*}
...
    return [
           'price',
            ..*other fields*
    ];
    }

The question is How can I remove the price from model and use another model's price attribute without too much pain?问题是如何从模型中删除价格并使用另一个模型的价格属性而不会有太多痛苦?

If you only want to show the price, you can do如果你只想显示价格,你可以这样做

class Product extends ActiveRecord
{
  ...
  public function getProductProperties()
  {
    return $this->hasOne(ProductProperties::class, ['product_id' => 'id']);
  }

  public function getPrice() {
    return $this->productProperties->price;
  }
  ...
}

And use it并使用它

$product = Product::findOne(1);
echo $product->price; // this is a shortcut 
echo $product->productProperties->price; // same as this which is the complete route

To save the data, you should first determine how to handle the user data collection, since you have different models and each one has its own validations.要保存数据,您应该首先确定如何处理用户数据收集,因为您有不同的模型并且每个模型都有自己的验证。

However, if you want to save the price as a Product attribute (I don't recommend it), you could do the following但是,如果您想将价格保存为产品属性(我不推荐),您可以执行以下操作

class Product extends ActiveRecord
{
  public $price;
  public function rules () {
    return [
      [['price'], 'integer'] // for massive assignment
    ];
  }

  public function afterFind()
  {
    parent::afterFind();
    $this->price = $this->productProperties->price;
  }

  public function getProductProperties()
  {
    return $this->hasOne(ProductProperties::class, ['product_id' => 'id']);
  }

  public function afterSave($insert, $changedAttributes)
  {
    parent::afterSave($insert, $changedAttributes);
    if (array_key_exists('price', $changedAttributes)) {
      // You should make sure that $this->productProperties exists.
      $this->productProperties->price = $this->price;
      $this->productProperties->save();
    }
  }
  ...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM