如何在Laravel中的http控制器中的条件上切换接口的自定义实现

时间:2019-04-04 10:21:28

标签: laravel laravel-5

我的控制器中有一个方法,该方法基本上只是将表单存储到数据库中。 我的表格很大,有30-40多个字段。 所以我需要在某种情况下将此信息存储在不同的3个表中。

例如:

foreach($request->all() as $answer):

    if($answer->employeeType === 1){

    //store data to type_one_table

   } else if($answer->employeeType === 2){

     //store data to type_two_table

   } else if($answer->employeeType === 3){

     //store data to type_two_table

  } else {

    //store data to some_other_table

    }

endforeach;

因此,我正在考虑使用一些自定义StoreInterface,它将具有一些store方法。

并将上述逻辑提取到自己的实现中。

然后在我的Controllers构造函数中接收该接口实例。

但是对于特定条件,我该如何称呼我需要哪个implementation

我可以做一个控制器吗?

或者在这种情况下我应该使用其他策略吗?

请引导我。

谢谢。

2 个答案:

答案 0 :(得分:0)

可以有很多方法。

我将建议我个人使用的2种方法:

1) 为每种情况创建一个雄辩的口才模型。

例如:

if($answer->employeeType === 1){
     EmployeeOne::create($answer);
}

您的雄辩模型看起来像:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use DB;

class EmployeeOne extends Model
{
    protected $table = 'type_one_table';

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        // your db field names
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
    ];

    public $timestamps = false;
}

确保传递给create函数的数组的数组键必须与db字段匹配。我只是为您提供了第一个if的示例,因此您可以从这里开始。

2) 另一种方法是创建一个将表名作为参数接受的模型。因此,基于您的if,您将传递要插入的表名和要插入的数据。

if($answer->employeeType === 1){
    $this->myModel->insertData($answer,'type_one_table');
}

在模型中,您将拥有类似的东西:

public function insertData($answer,$table){
    $query = DB::table($table)->insertGetId($answer); // returns the id of the new record

    return $query;
}

因此,在每个if-else语句中,只需更改传递给模型函数的表名即可。

答案 1 :(得分:0)

您可以具有如下常规界面:

interface EmployeeStoreContract
{
    public function saveAnswer();
}

然后以所有不同的方式保存答案,例如:

class FirstTypeEmployee implements EmployeeStoreContract
{
    public function saveAnswer()
    {
        // do something
    }
}

然后在您的控制器中找出如何保存请求数据:

public function store()
{
    $employeeTypesMap = [
        1 => 'FirstTypeEmployee',
        2 => 'SecondTypeEmployee',
        3 => 'ThirdTypeEmployee',
    ];

    foreach ($request->all() as $answer) {
        $employeeType = $answer->employeeType;

        if (!array_key_exists($employeeType, $employeeTypesMap)) {
            throw new \InvalidArgumentException('Answer type is not available.');
        }

        $employeeStrategyClass = "App\\Service\\Employee\\{$employeeTypesMap[$employeeType]}";
        $employeeStrategyObject = new $employeeStrategyClass;

        $employeeStrategyObject->saveAnswer($answer);
    }
}

请注意,您拥有这些类App\Service\Employee的名称空间可以是您想要的任何名称。还可以随意创建一个抽象类或特征来重用每个员工类的某些功能。