Что Laravel - красноречивый помощью методов hasmany отношения, но также имеющая одну?

Что Laravel - красноречивый помощью методов hasmany отношения, но также имеющая одну?

17.12.2019 06:02:29 Просмотров 79 Источник

Я был по всему интернету и боролся с этим около 2 часов.

У меня есть модель пользователя, модель запуска и модель времени.

В реальном мире пользователь находится в гонке и получает свое время, введенное в базу данных вместе с USER_id и RUN_id.

Пользователь должен иметь только одну строку в таблице TIMES для каждого RUN_id - если это имеет смысл!

Это то, что мне нужно управлять на уровне контроллера? Или есть связь, которую я могу настроить, чтобы гарантировать, что дубликат записи этого стиля не может войти в базу данных?

Структура базы данных в настоящее время:


ПОЛЬЗОВАТЕЛИ:

имя


БЕЖИТ:

имя


РАЗ:

время

идентификатор пользователя

run_id


модель:

ПОЛЬЗОВАТЕЛЬ:

public function times()
{
    return $this->hasMany(Time::class);
}

БЕЖАТЬ:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Run extends Model
{    
    public function user()
    {
        return $this->belongsTo(User::class);
    }

    public function times()
    {
        return $this->hasMany(Time::class);
    }
}

ВРЕМЯ:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Time extends Model
{
    public function user()
    {
        return $this->belongsTo(User::class);
    }

    public function run()
    {
        return $this->belongsTo(Run::class);
    }

}
У вопроса есть решение - Посмотреть?

https://stackoverflow.com/questions/59376944/laravel-eloquent-relationship-hasmany-but-also-hasone#comment104946299_59376944
Что такое групповое отношение в пользовательской модели?
https://stackoverflow.com/questions/59376944/laravel-eloquent-relationship-hasmany-but-also-hasone#comment104946319_59376944
пользовательская таблица должна иметь поле id, которое является первичным ключом, и таблицу времени тоже.
https://stackoverflow.com/questions/59376944/laravel-eloquent-relationship-hasmany-but-also-hasone#comment104946460_59376944
@L. Fox - это отдельные отношения, я удалю сверху
https://stackoverflow.com/questions/59376944/laravel-eloquent-relationship-hasmany-but-also-hasone#comment104946463_59376944
Есть ли у пользователя связь с запуском?
https://stackoverflow.com/questions/59376944/laravel-eloquent-relationship-hasmany-but-also-hasone#comment104946481_59376944
@Eric-у них есть все обычные первичные ключи, я просто не указал их для примера
https://stackoverflow.com/questions/59376944/laravel-eloquent-relationship-hasmany-but-also-hasone#comment104946515_59376944
@L. Fox-не напрямую, нет - он не имеет отношения к run. Пользователь имеет отношение только к временам, которые имеют отношение к запуску
https://stackoverflow.com/questions/59376944/laravel-eloquent-relationship-hasmany-but-also-hasone#comment104946641_59376944
вы сделали миграционный код для таблицы времени ? если да, то в функции CreateTimesTable (в database\migration\xxxxx_create_times_table.php) вы устанавливаете индексы; на этом этапе вы можете установить уникальный индекс на основе run_id + user_id. смотрите здесь : stackoverflow.com/questions/20065697/…

Ответы - Что Laravel - красноречивый помощью методов hasmany отношения, но также имеющая одну? / Laravel - Eloquent Relationship hasMany but also hasOne?

Является ответом!
Alec Joy

17.12.2019 06:25:15

Вы можете добавить ограничение уникального ключа в таблицу times, чтобы применить уникальные комбинации user_id и run_id

$table->unique(['user_id, 'run_id']);

Чтобы проверить уникальность на уровне приложения, мы также можем добавить ограничение для проверки формы. Предполагая, что вы передаете как user_id, так и run_id в запросе на создание нового времени, вы можете добавить следующее В запрос формы

/**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'user_id' => Rule::unique('times')->where('run_id', $this->input('run_id'))
        ];
    }

    public function messages()
    {
        return [
            'user_id.unique' => 'A user may only have 1 time entry per Run'
        ];
    }

Это приведет к тому, что идентификатор user_id будет уникальным в таблице times, отфильтрованной по этому идентификатору запуска. Функция messages также возвращает более полезное сообщение об ошибке, так как "user_id должен быть уникальным" бесполезно в этой ситуации.

https://stackoverflow.com/questions/59376944/laravel-eloquent-relationship-hasmany-but-also-hasone/59377317#comment104947105_59377317
Это сработало, спасибо! Теперь мне придется опубликовать отдельный вопрос, я думаю :)
https://stackoverflow.com/questions/59376944/laravel-eloquent-relationship-hasmany-but-also-hasone/59377317#comment104947133_59377317
Как бы вы проверили это при добавлении строк в базу данных? Или это просто для целостности базы данных,а не для обработки Laravel?
https://stackoverflow.com/questions/59376944/laravel-eloquent-relationship-hasmany-but-also-hasone/59377317#comment104947317_59377317
Правила проверки Laravel также могут работать с составными ключами, позвольте мне попытаться что-то написать, и я отредактирую свой ответ
https://stackoverflow.com/questions/59376944/laravel-eloquent-relationship-hasmany-but-also-hasone/59377317#comment104947827_59377317
Хорошо, обновил ответ с помощью правила проверки формы, которое вы можете добавить.
https://stackoverflow.com/questions/59376944/laravel-eloquent-relationship-hasmany-but-also-hasone/59377317#comment104970530_59377317
Однако-теперь, когда я пытаюсь отправить время выполнения, я всегда получаю сообщение "пользователь может иметь только 1 запись времени за запуск" для каждого отдельного пользователя..
apokryfos

17.12.2019 06:44:29

Этот ответ должен дополнять принятый ответ. Вы все равно должны определить пару user_id, run_id как уникальный ключ. Однако в вашем случае пользователь и запуск имеют отношение N-N с timesв качестве сводной таблицы. Вы должны кодировать его как таковой.

Пользователь

public function runs()
{
    return $this->belongsToMany(Run::class, 'times')->withPivot('time');;
}

Бежать:

public function users()
{
    return $this->belongsToMany(User::class, 'times')->withPivot('time');
}

Затем вы можете получить их как:


$runs = User::find($userId)->runs; // Collection of all runs a user participated in
// $runs[X]->pivot->time has the time

Вы можете проверить документацию для получения дополнительной информации

https://stackoverflow.com/questions/59376944/laravel-eloquent-relationship-hasmany-but-also-hasone/59377664#comment104967619_59377664
Я хотел бы дать два ответа "лучший ответ". Сочетание этого и другого ответа помогло мне достичь общей цели. Это также, как я могу получить пользователей, которые не имеют пробега: $бегунов = пользователь::whereDoesntHave('работает', функция($В) использовать($прогон) { $м->где('run_id', $выполнить->идентификатор); })->whereHas("ролей", функция($Щ){ // получаем только пользователям определенных ролей и $Q->где("имя", "студент") ->orWhere("наименование", "Студент ПЛТ"); })->получить();
Закрыть X