【问题标题】:Yii2 extending Gii CRUD with many-to-many form elementsYii2 使用多对多表单元素扩展 Gii CRUD
【发布时间】:2015-06-03 14:54:57
【问题描述】:

我有以下 3 个表:

Rule
-id
-name

CombinedRule
-id
-name

RuleCombineMapping
-id_rule
-id_combine

我为 Rule 和 CombinedRule 表生成了一个 CRUD。在 CombinedRule 模型类中,我创建了一个映射,该类如下所示:

<?php

namespace app\models;

use Yii;

/**
 * This is the model class for table "combinedrule".
 *
 * @property integer $id
 * @property string $name
 */
class CombinedRule extends \yii\db\ActiveRecord {

    /**
     * @inheritdoc
     */
    public static function tableName() {
        return 'combinedrule';
    }

    /**
     * @inheritdoc
     */
    public function rules() {
        return [
            [['name'], 'string', 'max' => 255],
            [['name'], 'unique']
        ];
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels() {
        return [
            'id' => 'ID',
            'name' => 'Name',
        ];
    }

    public function getRules() {
        return $this->hasMany(Rule::className(), ['id' => 'id_rule'])
                        ->viaTable(RuleCombineMapping::tableName(), ['id_combine' => 'id']);
    }

}

没有成功,我尝试通过在CombinedRuleController 中使用以下行来访问某个组合规则的规则。

$t = CombinedRule::find($id);
var_dump($t->rules);

结果始终是“未知属性”异常。

现在我不仅要查看/更新/读取/删除规则和组合规则,还要查看这两者之间的关系。

我知道这在其他使用原则的框架中是可能的,而且我也知道如何手动执行此操作,首先获取关系,然后将其添加到列表中。

现在有人有一个工作示例,如何使用类似的已建立数据结构映射这些表,并使用其前端模型、视图和表单将其尽可能容易地集成到 Gii CRUD 中?

【问题讨论】:

  • getRules() 看起来不错。但是,您可以尝试将方法体替换为return [];,以查看异常是否消失。您还可以重命名 Rule 类和方法,以确定它是否与 Model::rules() 冲突。 docshere 中提供了示例。
  • 我已经阅读了您指出的两个网站,遗憾的是我无法在那里找到帮助。 [] 括号也无济于事。甚至更改该物业的名称也无济于事....我真的被困住了。我什至考虑编写自己的查询!
  • $t 真的是一个 CombinedRule 对象吗? CombinedRule::find($id) 是 gii 默认生成的实现吗?当你 var_dump 时你看到了什么?
  • 我得到一个ActiveQueryclass 和public 'modelClass' =&gt; string 'app\models\CombinedRule' (length=23)
  • 这是一个提示。您得到的是未执行的 ActiveQuery 对象,而不是预期的 Rule 数组。所有 3 个类都继承自 ActiveRecord?您也可以发布您的模型类。而且你没有覆盖 getAttribute 或类似的东西?

标签: php many-to-many yii2


【解决方案1】:

我自己现在已经尝试过了,它对我有用。也就是说,视图文件中的var_dump($model-&gt;rules); 按预期给了我一个包含 Rule 对象的数组。

这是我的 gii 生成的文件。我已经从模型类中删除了 cmets、attributeLabels()、rules() 方法,从控制器类中删除了 action 方法和 behavior()。所以这是使 $model->rules 工作所需的基本代码:

规则

class Rule extends \yii\db\ActiveRecord {
    public static function tableName() {
        return 'rule';
    }
}

组合规则

class CombinedRule extends \yii\db\ActiveRecord {
    public static function tableName() {
        return 'combined_rule';
    }

    // Added this manually, this does not come from gii!
    // It is the single code that I've added.
    public function getRules() {
        return $this->hasMany(Rule::className(), ['id' => 'id_rule'])
            ->viaTable(RuleCombineMapping::tableName(), ['id_combine' => 'id']);
    }
}

规则组合映射

Gii 还生成了两个方法 getIdCombine()getIdRule(),这对于该问题也不是必需的。

class RuleCombineMapping extends \yii\db\ActiveRecord {
    public static function tableName() {
        return 'rule_combine_mapping';
    }
}

CombinedRuleController

class CombinedRuleController extends Controller {

    public function actionView($id) {
        return $this->render('view', [
            'model' => $this->findModel($id),
        ]);
    }

    protected function findModel($id) {
        if (($model = CombinedRule::findOne($id)) !== null) {
            return $model;
        } else {
            throw new NotFoundHttpException('The requested page does not exist.');
        }
    }
}

views/combined-rule/view.php

刚刚添加var_dump($model-&gt;rules);。其他是gii生成的代码。

use yii\helpers\Html;
use yii\widgets\DetailView;

$this->title = $model->title;
$this->params['breadcrumbs'][] = ['label' => 'Combined Rules', 'url' => ['index']];
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="combined-rule-view">

    <h1><?= Html::encode($this->title) ?></h1>

    <p>
        <?= Html::a('Update', ['update', 'id' => $model->id], ['class' => 'btn btn-primary']) ?>
        <?= Html::a('Delete', ['delete', 'id' => $model->id], [
            'class' => 'btn btn-danger',
            'data' => [
                'confirm' => 'Are you sure you want to delete this item?',
                'method' => 'post',
            ],
        ]) ?>
    </p>

    <?= DetailView::widget([
        'model' => $model,
        'attributes' => ['id', 'title'],
    ]) ?>

    <?php
        // And here it is: an array of Rule objects!!!!! 
        var_dump($model->rules);
    ?>
</div>

【讨论】:

  • 您的代码对我有用!谢谢!为什么要在RuleCombineMapping 中添加映射?你知道如何进一步处理 CombinedRuleController 中的Rules,例如更新/创建?
  • @lony 对不起,我不明白你在问什么。你的意思是getIdCombine() 和getIdRule() 吗?它们是由 gii 生成的。我现在删除了它们,因为它们看起来不是必需的。我还删除了一些其他不必要的代码。请看看这是否也适合您。知道您的代码与此处的代码有何不同会很有趣。你能找出来告诉我们吗?您想了解有关更新/创建的哪些信息?
  • 是的,我的意思是getIdXYthingy。这不是为我生成的。你也用yii-basic-app-2.0.4吗?
  • @lony 是的,我做到了。我可能在 gii 中使用了其他设置。无论如何,方法并不重要。
  • 我进一步调试了这个!问题似乎是在控制器内部缺少访问模型属性甚至模型本身的东西。里面的景色还不错! public function actionView($id) {$t = CombinedRule::find($id); var_dump($t-&gt;rules); }
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-06
  • 2016-09-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多