За последние 24 часа нас посетили 20058 программистов и 1082 робота. Сейчас ищут 700 программистов ...

Отношения вместо сырого запроса

Тема в разделе "Laravel", создана пользователем lordconst, 1 май 2020.

  1. lordconst

    lordconst Новичок

    С нами с:
    7 дек 2019
    Сообщения:
    151
    Симпатии:
    1
    Имеется задача, которую я уже решил с помощью сырого запроса с фасадом DB. Изначально пробовал сделать это через отношения, но в итоге из документации не понял как оно должно быть правильно. Просьба показать как это будет решено с помощью отношений. Прилагаю схему бд и свой код.
    Задача такова: при создании нового тикета, чтобы в поле person_id таблицы tickets прописывалось значение текущей персоны.
    Мой рабочий код:
    PHP:
    1. $person_id = DB::table('users')
    2.             ->join('persons', 'persons.user_id', '=', 'users.id')
    3.             ->where('users.id', '=', Auth::user()->id)
    4.             ->value('persons.id');
    А вот отношения м/у моделями:
    PHP:
    1. class Ticket extends Model
    2. {
    3.     protected $dates = ['date_off'];
    4.  
    5.     public function person() {
    6.         return $this->belongsTo('App\Person');
    7.     }
    8. }
    PHP:
    1. class Person extends Model
    2. {
    3.     protected $table = 'persons';
    4.  
    5.     public function user() {
    6.         return $this->belongsTo('App\User');
    7.     }
    8. }
    p.s. просьба не тыкать в документацию, т.к. уже читал и пробовал сделать.
    p.p.s. да, я читал про связь через промежуточную таблицу, но не смог это реализовать в моем случае.
    p.p.p.s. дополнительно была мысль, чтобы при авторизации записывать в сессию значение person_id, но решил отказаться от нее.
     

    Вложения:

  2. lordconst

    lordconst Новичок

    С нами с:
    7 дек 2019
    Сообщения:
    151
    Симпатии:
    1
    Что, никто не знает? Где же любители покидаться ссылками на документацию?
     
  3. denis01

    denis01 Суперстар
    Команда форума Модератор

    С нами с:
    9 дек 2014
    Сообщения:
    12.230
    Симпатии:
    1.715
    Адрес:
    Молдова, г.Кишинёв
    Я тут. https://laravel.com/docs/7.x/eloquent-relationships#the-save-method
    C laravel не знаком, так что лучше уточни какая версия и ORM
     
  4. lordconst

    lordconst Новичок

    С нами с:
    7 дек 2019
    Сообщения:
    151
    Симпатии:
    1
    Вроде бы последняя. Я копировал команды с документации.
    Спасибо, это не то, что нужно именно в этом вопросе, но тоже пригодится мне в этом проекте. Это сохранение данных в таблицу, а мне нужна выборка для вывода на экран
    У кого-нибудь еще есть мысли?
     
  5. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.548
    Симпатии:
    1.754
    Так тут главная модель user, по логике запроса. А её ты и не показал
    --- Добавлено ---
    PHP:
    1. class User extends Authenticatable
    2. {
    3.    public function person() {
    4.        return $this->hasOne(Person::class);
    5.    }
    6. }
    7.  
    8. $person = Auth::user()->person;
    Не помню, тебе или нет я показывал, что Illuminate\Foundation\Auth\User, скрывающийся за Authenticatable, наследуется от Illuminate\Database\Eloquent\Model, соответственно, у него тоже есть все методы has*, belongsTo и т.п.
    --- Добавлено ---
    Вот тебе несколько фрагментов моего кода. У пользователя есть посты
    PHP:
    1. // В классе User, естественно
    2. public function posts()
    3. {
    4.     return $this->hasMany(Post::class, "author_id");
    5. }
    И вот я в контроллере получаю посты текущего пользователя
    PHP:
    1. public function my()
    2. {
    3.     return $this->currentUser->posts()->returnedFirst()->with("author")->paginate(30);
    4. }
    returnedFirst - это такой scope у меня, чтоб посты, которые модератор вернул на доработку, возвращались первыми. with("author") ещё раз запрашивает, на самом деле, того же currentUser, но +/- один запрос не критично, зато удобно, не надо руками подставлять currentUser
     
    denis01 нравится это.
  6. lordconst

    lordconst Новичок

    С нами с:
    7 дек 2019
    Сообщения:
    151
    Симпатии:
    1
    Спасибо, приму к сведению. Помог один человек, решение оказалось донельзя простым:
    PHP:
    1. $myTickets = User::with('person.tickets')->find(Auth::user()->id);
     
    denis01 нравится это.
  7. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.548
    Симпатии:
    1.754
    Auth::user() - это уже экземпляр модели User, можно просто написать, если ваша конструкция работает:
    PHP:
    1. Auth::user()->person->tickets
    Не нужно ещё раз пользователя искать. Кстати, в твоём коде ты не билеты получаешь, а скорее, пользователя с его билетами. With больше нужен для запросов, когда больше одного экземпляра модели со связями нужно получить. В твоём случае от него по кол-ву запросов никакого выигрыша.

    Ну и стоит начинать уже соображать такие вещи из доки, это не что-то гениальное, это самые основы.