Laravel - Полиморфные отношения для типов моделей - PullRequest
0 голосов
/ 18 октября 2019

Я новичок в Laravel и в качестве своего первого проекта я пытаюсь создать API для опроса.

Я изо всех сил пытаюсь создать модель и контроллер для типов ответов, после того, как посмотрел его о своемвопрос, который я узнал о полиморфных отношениях, и это в какой-то мере отвечает тому, что мне нужно. Адам Уотхэм снял хорошее видео о модели и типах моделей, но не говорит о его создании.

Ссылка на видео: https://adamwathan.me/2015/09/03/pushing-polymorphism-to-the-database/

МОДЕЛИ

Я создал модель для ответов и типов ответов, и мне пришлось добавить тип атрибута в Ответы , потому что я должен заранее знать, какой это тип. Я решил добавить morphTo на модель типа, потому что я хочу, чтобы ни один или много Типы (текст, число) в моем ответе:

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'
    ]);
}

AnswerController

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);
    }

}

ВОПРОС

Я немного растерялся из-за того, что мне делать, потому что во время обучения я хочу знать, есть ли другой способ, которого я не вижу. Есть лучший способ добиться этого?

Ответы [ 2 ]

0 голосов
/ 19 октября 2019

Возможно, я говорю вне очереди и не из Ларавеллы. Исходя из фона СУБД, полиморфные отношения представляют собой красный флаг . Это не значит, что они всегда плохой дизайн (это было бы слишком легко), но они по своей сути проблематичны. Главным образом, потому что многие элементы управления реляционной целостностью вы можете получить декларативно, а за «бесплатно» в СУБД выбрасываются. Опять же, полиморфные отношения имеют тенденцию возникать в тех случаях, когда реляционная модель неудобно подходит. (Вид отношений.) Я использую такие отношения время от времени, но редко .... и с большим количеством размышлений заранее. Я полагаю, что в Laravel спрятаны беспорядочные отношения, поэтому Laravel, возможно, уже каким-то образом преодолел многие проблемы для вас. (Как уже отмечалось, я понятия не имею.) А если Postgres - это просто механизм персистенции для Laravel, возможно, это не так важно.

Вы не спрашивали о полиморфных отношениях как таковых, так чтоЯ оставлю это на этом. Но если вам интересна эта тема, глава Билла Карвина по теме в SQL Anitpatterns довольно хороша.

0 голосов
/ 18 октября 2019

Как только вы установите полиморфное отношение, оно действует как нормальное отношение в своем роде. Таким образом, вы используете морфинг «многие ко многим», он работает так же, как обычные «многие ко многим» для всех методов.

Наконец, вы можете рассмотреть возможность сохранения своего ответа в виде типа столбца JSON. В вашем конкретном случае это кажется более подходящим.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...