【问题标题】:Yii 2: Populate Another Table after Saving Data to One Table using values of the saved data tableYii 2:使用保存的数据表的值将数据保存到一个表后填充另一个表
【发布时间】:2017-05-25 17:16:45
【问题描述】:

我有两张表:Stations 和 Routes。 station 表有列(station_id、address、office_hours、date_create),Routes 表有列(routes_id、from_id、destination_id)。 Routes 表中的 from_id 和 destination_id 是引用站表的外键。

现在我想做的是每当添加一个车站时,该车站的路线是使用表中已有的车站计算的。例如,假设我们在站表中已经有站 A。将 B 站结果添加到两条路线 A-->B 和 B-->A 其中对于路线 A-->B,A =>from 而 B => 目的地,因此它们的 ID 仅在路线表中被挑选和填充相应地。

我在工作站控制器中尝试了以下代码,但没有成功。代码是:

站控制器:

public function actionCreate()
{
    $model = new Stations();

    $routesModel = new Routes();

    //checking whether we are getting the logged in user id value
    Yii::info("User id=".Yii::$app->user->id); 

    $model->registered_by_id = Yii::$app->user->id;

    $model->status = 10;

    if ($model->load(Yii::$app->request->post()) && $model->save()) {

        //checking here the saved user id value in  table
        Yii::info("checking User id after saving model=".$model->registered_by_id);

        $this->createRoutes($model->station_id);

        return $this->redirect(['view', 'id' => $model->station_id]);
    } else {
        return $this->render('create', [
            'model' => $model,
        ]);
    }
}

public function createRoutes($id)
{
    $model = new Routes;

    $command = Yii::$app->db->createCommand('SELECT station_id FROM stations WHERE station_id !='.$id);
    $all_stations = $command->queryAll();

    foreach ($all_stations as $new_route) {
        $from_id = $id;
        $destination_id = $new_route;
        $model->load(Yii::$app->request->post()) && $model->save();
        $from_id = $new_route;
        $destination_id = $id;
        $model->load(Yii::$app->request->post()) && $model->save();
    }

    return;
}

站表已填充,但路线表未填充。但是,我没有收到任何错误。我哪里出错了?

请尽可能提供帮助。

修改函数createRoutes()

public function createRoutes($id)
{
    $model = new Routes;

    $count = (new \yii\db\Query())->from('stations')->count();

    if($count > 1) {
        $command = Yii::$app->db->createCommand('SELECT station_id FROM stations WHERE station_id !='.$id);
        $all_stations = $command->queryAll();

        foreach ($all_stations as $new_route) {
            $model->from_id = $id;
            $model->destination_id = $new_route['station_id'];
            $model->save();
            $model->from_id = $new_route['station_id'];
            $model->destination_id = $id;
            $model->save();
        }
        return;
    }
    else
        return;
}

现在,在进行上述更改后,它只将一条路线保存到数据库中,但有几个车站,因此应该创建几条路线。如果我有 10 个站,它只会生成站 9 到 10 的路线;我的假设是它只保存 foreach 外观的最后一点,在其他情况下,不会调用 $model->save() 参数。我在这里做错了吗?

【问题讨论】:

    标签: mysql yii2 models


    【解决方案1】:

    在您的 createRoutes 方法中,您只创建了一个 Routes 模型并填充它并将其保存在循环中,这就是您只获得一条记录的原因。相反,您只需要像这样在 foreach 中创建新模型:

    public function createRoutes($id)
    {
        //$model = new Routes; not here
    
        // $command = Yii::$app->db->createCommand('SELECT station_id FROM stations WHERE station_id !='.$id);
        // $all_stations = $command->queryAll();
    
        // I am using  active record instead of single query, you can do anything you want here
        $all_stations = Stations::find()
                    ->where('station_id != :id', [':id' => $id])
                    ->all();
    
        foreach ($all_stations as $new_route) {
            $model = new Routes; // create record here
            $model->from_id = $id;
            $model->destination_id = $new_route->station_id;
            // no need to load because these data are not in request param
            // $model->load(Yii::$app->request->post()) && $model->save();
            $model->save();
    
            $model = new Routes; // and another one
            $model->from_id = $new_route->station_id;
            $model->destination_id = $id;
            $model->save();
        }
    
        return;
    }
    

    重构版本: 上面应该可以解决问题,但这里有另一个优化。

    Routes 模型中创建一个像这样的静态方法:

    public static function create($data)
    {
        $model = new self;
        $model->from_id = $data['from_id'];
        $model->destination_id = $data['destination_id'];
        return $model->save();
    }
    

    然后像这样重写createRoutes 方法:

    public function createRoutes($id)
    {
        $all_stations = Stations::find()
                    ->where('station_id != :id', [':id' => $id])
                    ->all();
    
        foreach ($all_stations as $new_route) {
            Routes::create([
                'from_id' => $id,
                'destination_id' => $new_route->station_id,
            ]);
    
            Routes::create([
                'from_id' => $new_route->station_id,
                'destination_id' => $id,
            ]);
        }
    
        return;
    }
    

    而且我们现在有了更简洁的版本。

    【讨论】:

    • 感谢您的解决方案@leninhasda,我已按照建议修改了代码,它的工作原理就像一个魅力。事实上,我注意到插入值所需的时间与以前不同。 虽然有一个更正。createRoutes() 函数的最后一部分中,您有一个错字,您使用了Rooutes:: 而不是Routes::。我试图编辑,但它正在重新发布我之前发布的答案。否则,非常感谢。
    • 你能回答我之前问的这个问题吗? link
    • 啊... 不错 @japheth 并感谢您的错字报告,现在已修复。我会查看您的链接,如果可以,我一定会尝试回答。
    【解决方案2】:

    也许 Yii::$app->request->post() 在函数 createRoules 中不起作用,因为它不是一个动作函数,但你可以使用 $model->getErrors() 来查找模型中的错误

    【讨论】:

    • 感谢您的洞察@vasillis,我已经对代码进行了一定程度的修改,直到它现在可以工作。问题是它不是将所有路由都插入到数据库中,而是只插入foreach循环的最后一个路由,其他所有生成的路由都没有插入;因此只插入了一条路线。让我更新上面的代码。
    • 最后,我能够将 $model-> 命令更改为 $sql = 'INSERT INTO routes(from_id, destination_id) VALUES('.$from_id.','.$destination_id.') '; Yii::$app->db->createCommand($sql)->execute();
    【解决方案3】:

    我知道这很粗略,对系统的查询时间意义重大,但我正在拼命寻找答案。所以到目前为止这对我有用;

    public function actionCreate()
    {
        $model = new Stations();
    
        $routesModel = new Routes();
    
        //checking whether we are getting the logged in user id value
        Yii::info("User id=".Yii::$app->user->id); 
    
        $model->registered_by_id = Yii::$app->user->id;
    
        $model->status = 10;
    
        if ($model->load(Yii::$app->request->post()) && $model->save()) {
    
            //checking here the saved user id value in  table
            Yii::info("checking User id after saving model=".$model->registered_by_id);
    
            $this->createRoutes($model->station_id);
    
            return $this->redirect(['view', 'id' => $model->station_id]);
        } else {
            return $this->render('create', [
                'model' => $model,
            ]);
        }
    }
    
    public function createRoutes($id)
    {
        $model = new Routes;
    
        $count = (new \yii\db\Query())->from('stations')->count();
    
        if($count > 1) {
            $command = Yii::$app->db->createCommand('SELECT station_id FROM stations WHERE station_id !='.$id);
            $all_stations = $command->queryAll();
    
            foreach ($all_stations as $new_route) {
                $from_id = $id;
                $destination_id = $new_route['station_id'];
                $sql = 'INSERT INTO routes(from_id, destination_id) VALUES('.$from_id.','.$destination_id.')';
                Yii::$app->db->createCommand($sql)->execute();
                // $model->save();
                $from_id = $new_route['station_id'];
                $destination_id = $id;
                $sql = 'INSERT INTO routes(from_id, destination_id) VALUES('.$from_id.','.$destination_id.')';
                Yii::$app->db->createCommand($sql)->execute();
                // $model->save();
            }
            return;
        }
        else
            return;
    }
    

    我仍然欢迎更好的解决方案,尤其是使上述解决方案如此高效。谢谢各位。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-22
      相关资源
      最近更新 更多