【问题标题】:yii2 - fill table with data from two tables from databaseyii2 - 用数据库中两个表中的数据填充表
【发布时间】:2020-04-27 08:28:34
【问题描述】:

我用过 Yii 和 Yii2 几次......每次我使用它时,我都会迷失在这个框架上。实际上,Yii 非常强大,它为你做了很多事情,但有时你会因此而迷失方向,你不知道发生了什么,也不知道如何做一些简单的事情。现在我正在尝试用来自 2 个相关表的数据填充一个表。我读过 Yii 论坛、stackoverflow 主题、youtube ......但没有任何效果。我的配置是 Yii2 高级的。

在 postgres 中,我有两个表:

  • 带有字段“id(int)”和“tool_name(varchar)”的表“工具”。
  • 表 'options' 包含字段 'id(int)'、'tool_id(int - 来自工具的外键)'、'option_name(varchar)'、'type(int)'。

问题是,在我的选项/索引中,我想在表格中显示工具名称,如下所示(GridView?):

|工具名 |选项名称 |输入 |

另一个选项可能是通过 DropDownList 过滤表格,我可以在其中选择一个工具并更新表格。如果未选择任何工具,则显示所有数据。我不知道哪个选项更简单,两者都对我有效。

有人可以给我看一些灯吗?我会很感激的...谢谢!!

【问题讨论】:

    标签: gridview yii2 dropdown


    【解决方案1】:

    最好的方法是使用在活动模型中实现的关系。

    1) 在模型中定义关系

    如果您使用 Gii 从数据库生成模型类,那么关系可能已经定义。

    应该是这样的

    class Option extends \yii\db\ActiveRecord
    {
        public function getTool()
        {
            return $this->hasOne(Tool::class, ['id' => 'tool_id']);
        }
        
        //... other code of the model
    }
    

    在模型类中定义关系将允许您访问相关模型作为该对象的属性。例如,上面定义的方法将允许您执行 $option->tool->tool_name 之类的操作。

    2) 强制加载关系

    默认情况下,Yii 中的关系使用“延迟加载”。这意味着相关模型在第一次访问之前不会从数据库中加载。当您使用单个模型时这很好,因为您可能会或可能不会使用该相关模型。但是,如果您要在表中输出多个模型并且每个模型都将访问相关模型,则延迟加载将导致对表的每一行进行额外查询。 为了避免这种情况,我们想对ActiveQuery 说,它应该在加载option 模型时为我们的tool 关系加载所有相关模型。这称为“急切加载”。为此,您必须在为数据提供者创建查询时使用with() 方法。

    例如这样:

    $query = Option::find()
      ->with('tool'); //the param is name of relation
    

    3) 将列从相关模型添加到 GridView

    现在您可以简单地将相关模型中的列添加为relation.column,在您的情况下,它将是tool.tool_name

    例子:

    <?= yii\grid\GridView::widget([
        'dataProvider' => $dataProvider,
        'filterModel' => $searchModel,
        'columns' => [
            'tool.tool_name',
            'option_name',
            'type',
        ]
    ]);
    

    【讨论】:

      【解决方案2】:

      在选项模型中你需要添加以下内容

          public function getTools()
          {
              return $this->hasOne(Options::className(), ['id' => 'tool_id']);
          }
      
      
          public function getToolName() {
              return $this->tools->tool_name;
          }
      

      那么在toolName的gridview中就会有一个可用的字段

      【讨论】:

        【解决方案3】:

        您要查找的是 relations

        在您的工具模型中将是 hasMany

        public function getOptions() {
          return $this->hasMany(Options::className(), ['tool_id' => 'id']);
        }
        

        还有一个 hasOne 在您的选项模型中:

        public function getTool() {
          return $this->hasOne(Tools::className(), ['id' => 'tool_id']);
        }
        

        现在$model = Tools::find()-&gt;all() 还将通过$model-&gt;options 为您提供相关数据。对于选项,反之亦然。

        由于您可能想要所有工具和所有选项,因此您的 $dataProvider 将是选项,而不是工具。对于每个选项,您都会获得相关的工具。

        相关数据可以在gridview中显示

         [
         'attribute' => 'tools',
         'value' => 'tools.tool_name'
         ],
        

        请参阅this article 以供参考。

        此外,Gii 会为您生成这些关系,如果您使用它创建模型。 (请注意,如果您不在 localhost 上工作,则需要在 allowedIPs 中设置您的 IP 地址,否则它不会显示。)

        【讨论】:

        • 方法 className() 自版本 2.0.14 起已弃用。建议改用::class 魔术常量。我也不完全明白你为什么将count() 方法调用放在关系定义中。关系定义应该返回 ActiveQuery 实例。
        • 我从我的一个文件中复制了一些代码,但没有删除 count(),你是对的。修好了。
        猜你喜欢
        • 1970-01-01
        • 2019-07-09
        • 2014-10-23
        • 1970-01-01
        • 1970-01-01
        • 2016-04-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多