За последние 24 часа нас посетили 17859 программистов и 1608 роботов. Сейчас ищут 1369 программистов ...

Многие ко многим

Тема в разделе "Laravel", создана пользователем Dimon2x, 28 июн 2018.

  1. Dimon2x

    Dimon2x Старожил

    С нами с:
    26 фев 2012
    Сообщения:
    2.210
    Симпатии:
    185
  2. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.583
    Симпатии:
    1.761
    @Dimon2x, ну только с одной стороны рассмотрел. Ведь ещё же в одной категории может быть много статей. А значит что? Значит со второй стороны должно быть тоже n. А если с обеих сторон n, то многие-ко-многим. МОжет я вечером неясно написал, но ты при составлении таких схем ты рассматриваешь вопрос с двух сторон, т.е. в данном случае, сколько категорий у статей сначала, рядом с категориями пишешь 1 или n (или конкретное число, такое тоже бывает), а потом смотришь в обратную сторону, сколько статей у категории, и соответственно уже ставишь число рядом с категориями. Understand?
     
    Dimon2x нравится это.
  3. Dimon2x

    Dimon2x Старожил

    С нами с:
    26 фев 2012
    Сообщения:
    2.210
    Симпатии:
    185
    @mkramer я чуть неправильно подумал
     
  4. Dimon2x

    Dimon2x Старожил

    С нами с:
    26 фев 2012
    Сообщения:
    2.210
    Симпатии:
    185
    PHP:
    1. <?php
    2.  
    3. namespace App;
    4.  
    5. use Illuminate\Database\Eloquent\Model;
    6.  
    7. class Category extends Model
    8. {
    9.      public function article()
    10.     {
    11.         return $this->belongsToMany('App\Services\Image');
    12.     }
    13. }

    Как вывести статьи из пивотной таблицы с пагинатором?

    Делаю так, всё хорошо работает

    PHP:
    1. $aaa = Category::find(3);
    2.    
    3. dd($aaa->article);
    Но если добавить с пагинатором, то будет ошибка
    PHP:
    1. $aaa = Category::find(3)::paginate(2);
    2.    
    3. dd($aaa->article);
    Код (Text):
    1. Undefined property: Illuminate\Pagination\LengthAwarePaginator::$article
     
  5. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.583
    Симпатии:
    1.761
    Ты хоть пытаешься понять смысл того, что пишешь? Или ты просто так пишешь? Category::find(3) - это одна модель, а не много моделей. Зачем тебе одну модель пагинировать?

    А если ты много категорий получишь, то у каждой будет свой article, но не у всех сразу. И пагинатор ничего про твои связи естественно не знает, надо из него получить конкретную модель и работать дальше, если нужно.
     
  6. Dimon2x

    Dimon2x Старожил

    С нами с:
    26 фев 2012
    Сообщения:
    2.210
    Симпатии:
    185
    @mkramer как зачем, не выводить же огромный список.
    --- Добавлено ---
    Я же получил модель Image
     
  7. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.583
    Симпатии:
    1.761
    Какой огромный список? Category::find(3) возвращает одну модель, одну категорию с id 3. Всё.
    И у тебя имено в таком виде работает? С двумя двоеточиями?
     
  8. Dimon2x

    Dimon2x Старожил

    С нами с:
    26 фев 2012
    Сообщения:
    2.210
    Симпатии:
    185
    @mkramer с двумя
    --- Добавлено ---
    Я кажись начинаю понимать, надо сначала как-то зайти в метод article, а потом уже указывать пагинацию
     
  9. artoodetoo

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

    С нами с:
    11 июн 2010
    Сообщения:
    11.108
    Симпатии:
    1.243
    Адрес:
    там-сям
    разложи цепочку вызовов на отдельные шаги и в отладчике посмотри какого типа результат возвращает каждый метод.
    это тебя просветлит!
    --- Добавлено ---
    ( хотя врядли )
     
  10. ElisDN

    ElisDN Активный пользователь

    С нами с:
    13 фев 2018
    Сообщения:
    605
    Симпатии:
    130
    Код (Text):
    1. Category::find(3)->articles()->orderByDesc('created_at')->paginate(2)
     
    Dimon2x нравится это.
  11. igordata

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

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    @ElisDN ты дал ему решение в то время как его ведут к умению находить их самостоятельно. Хотя я согласен, что пора уже менять тактику.
     
  12. Dimon2x

    Dimon2x Старожил

    С нами с:
    26 фев 2012
    Сообщения:
    2.210
    Симпатии:
    185
    @igordata @ElisDN я так вчера делал, только без сортировки и почему-то не работало, вечером опять попробую
    --- Добавлено ---
    @artoodetoo я так каждый раз делаю
     
  13. nospiou

    nospiou Старожил

    С нами с:
    4 фев 2018
    Сообщения:
    3.400
    Симпатии:
    510
    @Dimon2x Сортировка тут не причем у тебя скорее всего связь в модели не создана
     
  14. romach

    romach Старожил

    С нами с:
    26 окт 2013
    Сообщения:
    2.904
    Симпатии:
    719
    Почему не по id?
     
  15. ElisDN

    ElisDN Активный пользователь

    С нами с:
    13 фев 2018
    Сообщения:
    605
    Симпатии:
    130
    Можно и по id, и по published_at.
     
  16. Dimon2x

    Dimon2x Старожил

    С нами с:
    26 фев 2012
    Сообщения:
    2.210
    Симпатии:
    185
    @ElisDN @romach @nospiou @artoodetoo @igordata @mkramer

    Надо вывести список постов, к какой категории относится пост, я это сделал с помощью построителя, так как не знаю, как это сделать, через ORM.

    3 таблицы:

    categories
    -id
    -name

    images
    -id
    -image
    -description

    category_image (промежуточная)
    -image_id
    -category_id

    PHP:
    1.  public function getCategoryTitle($id)
    2.     {  
    3.         $post = DB::table('category_image')
    4.                      ->where('image_id', '=', $id)
    5.                      ->get();
    6.         $categoryImage = $post->toArray()[0]->category_id;
    7.        
    8.        
    9.         $showCategory = DB::table('categories')
    10.                      ->where('id', '=', $categoryImage)
    11.                      ->get();
    12.        
    13.        return $showCategory->toArray()[0]->name;
    14.        
    15.     }

    Сейчас получается, что на каждый пост, будет ещё 2 запроса в базу, а это очень нехорошо.
    --- Добавлено ---
    посты вывожу так

    PHP:
    1.  public function index()
    2.     {
    3.         $posts = Image::all();
    4.      
    5.         return view('admin.posts.index', ['posts'=>$posts]);
    6.     }
    PHP:
    1. @foreach($posts as $post)
    2.                 <tr>
    3.                   <td>{{$post->id}}</td>
    4.                   <td>{{$post->description}}</td>
    5.                   <td>{{$post->getCategoryTitle($post->id)}}</td>
    6.                   <td>
     
  17. Dimon2x

    Dimon2x Старожил

    С нами с:
    26 фев 2012
    Сообщения:
    2.210
    Симпатии:
    185
    Пробую так, в модели постов

    PHP:
    1.  dd( $this->belongsToMany(
    2.             Category::class,
    3.             'category_image',
    4.             'image_id',
    5.             'category_id',
    6.                 1
    7.         ));
    А как теперь вывести имя категории?
    --- Добавлено ---
    Код (Text):
    1. шина  
    2. BelongsToMany {#494 ▼
    3.   #table: "category_image"
    4.   #foreignPivotKey: "image_id"
    5.   #relatedPivotKey: "category_id"
    6.   #parentKey: 1
    7.   #relatedKey: "id"
    8.   #relationName: "getCategoryTitle"
    9.   #pivotColumns: []
    10.   #pivotWheres: []
    11.   #pivotWhereIns: []
    12.   #pivotValues: []
    13.   +withTimestamps: false
    14.   #pivotCreatedAt: null
    15.   #pivotUpdatedAt: null
    16.   #using: null
    17.   #accessor: "pivot"
    18.   #query: Builder {#493 ▶}
    19.   #parent: Image {#473 ▶}
    20.   #related: Category {#490 ▶}
    21. }
     
  18. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.583
    Симпатии:
    1.761
    У тебя отношения "многие-ко-многим", значит у каждого изображения (почему ты упорно пишешь пост, а таблицу назвал images?) несколько категорий, а не одна.

    А дальше вообще какая-то у тебя магия вуду в коде....
    --- Добавлено ---
    Сделать belongsToMany (только по человечески) и жадную загрузку https://laravel.com/docs/master/eloquent-relationships#eager-loading
     
  19. Dimon2x

    Dimon2x Старожил

    С нами с:
    26 фев 2012
    Сообщения:
    2.210
    Симпатии:
    185
    мне на стековерфлов ответили

    in image model

    PHP:
    1. public function categories(){
    2. return $this->belongsToMany(Category::class)
    3. }
    in category model


    PHP:
    1. public function images(){
    2. return $this->belongsToMany(Image::class)
    3. }
    with() for eager loading, provides you to get categories in single query

    PHP:
    1. $posts = Image::with("categories")->get();
    2.  
    3. foreach($posts as $post) {
    4.   foreach ($post->categories as $category){
    5.      $category->name
    6.    }
    7. }

    --- Добавлено ---
    Теперь работает, как надо
    --- Добавлено ---
    Сразу всю доку сложно усвоить
     
  20. nospiou

    nospiou Старожил

    С нами с:
    4 фев 2018
    Сообщения:
    3.400
    Симпатии:
    510
     
  21. Dimon2x

    Dimon2x Старожил

    С нами с:
    26 фев 2012
    Сообщения:
    2.210
    Симпатии:
    185
    @nospiou тут без разницы, ка переменную обзывать.
     
  22. nospiou

    nospiou Старожил

    С нами с:
    4 фев 2018
    Сообщения:
    3.400
    Симпатии:
    510
    Тут недавно была тема о последствиях разработки шифровальных алгоритмов. Не боишься?
     
  23. Dimon2x

    Dimon2x Старожил

    С нами с:
    26 фев 2012
    Сообщения:
    2.210
    Симпатии:
    185
    @nospiou это пока я просто учусь
     
  24. igordata

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

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    да, но можешь ли ты это воспроизвести, не подглядывая? т.е. понял ли ты.
    а то так-то мне в линуксе ответили, как ядро написать.
     
  25. nospiou

    nospiou Старожил

    С нами с:
    4 фев 2018
    Сообщения:
    3.400
    Симпатии:
    510
    @Dimon2x А сколько вообще постов замаскированных под изображение планируется? может лучше paginate?