首页 > 解决方案 > Laravel - 模型类型的多态关系

问题描述

我是 Laravel 的新手,作为我的第一个项目,我正在尝试制作一个调查 API。

我正在努力为答案类型创建模型和控制器,在查看了我的问题后,我发现了多态关系,这在一定程度上满足了我的需求。Adam Watham 制作了一个关于模型和模型类型的好视频,但没有谈到创建它。

视频链接:https ://adamwathan.me/2015/09/03/pushing-polymorphism-to-the-database/

楷模

我为答案和答案类型创建了一个模型,并且必须在Answers上添加一个属性类型,因为我必须事先知道它是什么类型。我选择在类型模型上添加 morphTo 是因为我不希望我的答案中有很多Types(text,number) :

class NumberAnswer extends Model
{
    protected $fillable = [
        'number'
    ];

    public function numberable()
    {
        $this->morphTo();
    }
}

class TextAnswer extends Model
{
    protected $fillable = [
        'text'
    ];

    public function textable()
    {
        $this->morphTo();
    }
}

class Answer extends Model
{
    protected $fillable = [
        'user_id',
        'question_id',
        'type'
    ];

    public function numbers()
    {
        $this->morphMany('App\Models\File', 'numberable');
    }

    public function texts()
    {
        $this->morphMany('App\Models\Text', 'textable');
    }
}

我遇到的问题是如何存储它们,我目前的工作方式以及我在哪里找到了一些提示:

我发现的多态控制器解决方案

服务提供者

public function boot()
{
    Relation::morphMap([
        'answer' => 'App\Models\Answer'
    ]);
}

应答控制器

class AnswerController extends Controller
{
    private $answer;


    public function __construct(AnswerRepository $answerRepo)
    {
        $this->answer = $answerRepo;
    }

    public function store(Request $request, int $tenantId)
    {
       $requestAnswer = $request->validate([
         'user_id' => [
            'required',
            'numeric',
            Rule::exists('users','id'),
        ],
        'question_id' => [
            'required',
            'numeric',
            Rule::exists('questions','id'),
        ],
        'type' => [
            'required',
            'in:text,number'
        ]
       ]);

       $text = $request->validate([
           'text' => 'required_if:type,text|string',
       ]);
       $number = $request->validate([
           'number' => 'required_if:type,number|string',
       ]);

       $answer = $this->answer->create($requestAnswer);

       if($requestAnswer['type'] === 'text'){
          $answer->texts()->create(['text' => $text]);
       }
       if($requestAnswer['type'] === 'number'){
          $answer->numbers()->create(['number' => $number]);
       }

       return response()->json($answer);
    }

}

问题

我对我应该做什么有点迷茫,因为在我学习的过程中,我想知道是否还有另一种我看不到的方式。有更好的方法来实现这一目标吗?

标签: laravelpostgresqlmodel-view-controllerpolymorphism

解决方案


一旦你设置了多态关系,它就像一个正常的关系。因此,您正在使用多对多的变形,它与所有方法的常规多对多相同。

最后,您可能需要考虑将答案存储为 JSON 列类型。在您的特定用例中,它似乎更合适。


推荐阅读