За последние 24 часа нас посетили 22626 программистов и 1015 роботов. Сейчас ищут 718 программистов ...

Eloquent

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

  1. Dimon2x

    Dimon2x Старожил

    С нами с:
    26 фев 2012
    Сообщения:
    2.199
    Симпатии:
    184
    С методом save() можно получить id только что созданной записи

    PHP:
    1. $this->image = $fileName;
    2. $this->description = $description;
    3. $this->id_user = Auth::id();
    4. $this->save()
    5.  
    6. $this->id;
    А как это получить id, когда запись создаться методом create, или вообще нельзя?

    PHP:
    1. $this::create([
    2.             'image' => $fileName,
    3.             'description' => $description,
    4.             'id_user' => Auth::id()
    5.                 ]);
     
  2. nospiou

    nospiou Старожил

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

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

    С нами с:
    14 дек 2016
    Сообщения:
    471
    Симпатии:
    70
  4. nospiou

    nospiou Старожил

    С нами с:
    4 фев 2018
    Сообщения:
    3.400
    Симпатии:
    510
    Ну если $this = self::create($array); тогда возможно
    А вообще нужно делать по людски
    PHP:
    1. $post = self::create($array); // \App\Post::create($array);
    2. return $post->id;
    Если уж так хочется вынести в модель
     
    Dimon2x нравится это.
  5. villiwalla

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

    С нами с:
    14 дек 2016
    Сообщения:
    471
    Симпатии:
    70
    Димон доку на англ не читает ))
     
  6. nospiou

    nospiou Старожил

    С нами с:
    4 фев 2018
    Сообщения:
    3.400
    Симпатии:
    510
    Я потому ему на англ и подсовываю что бы начал:)
     
  7. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.553
    Симпатии:
    631
    В любой ситуации можно вытащить драйвер и пропросить last inserted id.
     
  8. Dimon2x

    Dimon2x Старожил

    С нами с:
    26 фев 2012
    Сообщения:
    2.199
    Симпатии:
    184
    @villiwalla вообще-то читаю
    --- Добавлено ---
    null
    --- Добавлено ---
    Так работает
     
  9. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.553
    Симпатии:
    1.754
    @Dimon2x, просто ты не сильно понимаешь, как работает $this::create(...). Эта дебильная форма записи работает ровно как self::create(...), и, соответственно, текущий $this не меняет.
     
  10. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.553
    Симпатии:
    631
    Более того, это она и есть, ведь T_PAAMAYIM_NEKUDOTAYIM без разницы.
     
  11. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.553
    Симпатии:
    1.754
    Ну для меня было странным открытие, что слева может быть любой экземпляр класса. Не представляю, нафига это сделано. Но не мне судить авторов PHP
     
  12. Dimon2x

    Dimon2x Старожил

    С нами с:
    26 фев 2012
    Сообщения:
    2.199
    Симпатии:
    184
    @mkramer почему дебильная?
     
  13. nospiou

    nospiou Старожил

    С нами с:
    4 фев 2018
    Сообщения:
    3.400
    Симпатии:
    510
    потому что..
    --- Добавлено ---
    PHP:
    1. $test = new Test;
    2. $test->int = 2;
    3. $test->intPlus2();
    4. $test->int; // 2 + 2 = 4
    Ты создаешь объект у которого есть свойства и методы которые знают друг о друге
    PHP:
    1. $intPlus2 = Test::intPlus2(2);
    Объект не создается. Никаких свойств и методов нет. Ты передаешь параметры и получаешь результат. Обращаться к статику через $this не правильно. Так как этот метод не имеет никакого отношения к конкретно созданному экземпляру объекта.
     
  14. keren

    keren Новичок

    С нами с:
    15 ноя 2017
    Сообщения:
    513
    Симпатии:
    42
    Может лучше привести пример в редакторе прежде чем говорить что без разницы?
     
  15. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.553
    Симпатии:
    1.754
    @keren, если ты перед :: ставишь экземпляр класса, то PHP, фактически, просто делает get_class, и у полученного класса вызывает указанный статический метод.

    Потому что такое поведение не очевидно.
     
  16. keren

    keren Новичок

    С нами с:
    15 ноя 2017
    Сообщения:
    513
    Симпатии:
    42
    Вместо теории лучше бы привел рабочий пример с "$this::create(...)."
     
  17. Dimon2x

    Dimon2x Старожил

    С нами с:
    26 фев 2012
    Сообщения:
    2.199
    Симпатии:
    184
    Как преобразовать код построителя запросов в Eloquent?

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

    Статьи могут быть добавлены в разные категории

    Метод addRelation получает массив с значениями категории и идентификатором статьи

    и после обработки эти данные добавляются к промежуточной таблице

    Код (Text):
    1. array:2 [▼
    2.   0 => "1"
    3.   1 => "2"
    4. ]
    Код (Text):
    1. public function addRelation($categories, $id)
    2.     {  
    3.         $categoryId = [];
    4.         $collection = collect($categories);
    5.         $collection = $collection->chunk(1);
    6.  
    7.         $collection->each(function ($item, $key) use (&$categoryId, $id){
    8.              $categoryId[] = [
    9.                    'image_id' => $id,
    10.                    'category_id' => $item->first()
    11.                    ] ;
    12.               }
    13.  
    14.           );
    15.  
    16.            DB::table('category_image')->insert($categoryId);
    17.     }
    Удаление

    Код (Text):
    1. public function deleteImage($image)
    2.     {  
    3.       Storage::delete($image->image);
    4.       $this->destroy($image->id);
    5.  
    6.       DB::table('category_image')->where('image_id', $image->id)->delete();
    7.     }
    Модели

    Код (Text):
    1. class Image extends Model
    2. {  
    3.  
    4.     public function categories()
    5.     {
    6.         return $this->belongsToMany(Category::class);
    7.     }
    8. }
    9.  
    10.  
    11. class Category extends Model
    12. {  
    13.      protected $fillable = ['name'];
    14.      public $timestamps = false;
    15.  
    16.  
    17.      public function article()
    18.     {
    19.         return $this->belongsToMany('App\Services\Image');
    20.     }
    21. }
    это типа меток длят статей


    /////////////////////////////////////////////////////////////

    Код (Text):
    1. Schema::create('categories', function (Blueprint $table) {
    2. $table->increments('id');
    3. $table->string('name');
    4. });
    Код (Text):
    1. Schema::create('images', function (Blueprint $table) {
    2.             $table->increments('id');
    3.             $table->string('image');
    4.             $table->timestamps();
    5.         });
    Код (Text):
    1. Schema::create('category_image', function (Blueprint $table) {
    2.             $table->increments('id');
    3.             $table->integer('image_id');
    4.             $table->integer('category_id');
    5.         });
     
  18. Dimon2x

    Dimon2x Старожил

    С нами с:
    26 фев 2012
    Сообщения:
    2.199
    Симпатии:
    184
    Почему выводит null?

    Код (Text):
    1. $relation = \App\Services\Image::find($idNewImage);
    2.        
    3. dd($relation->categories()->attach($categories));
     
  19. Dimon2x

    Dimon2x Старожил

    С нами с:
    26 фев 2012
    Сообщения:
    2.199
    Симпатии:
    184
    Вот такой запрос получился

    Код (Text):
    1. (SQL: insert into `category_image` (`category_id`, `image_id`, `0`, `1`) values (18, 18, 1, 2)
    Это неверный запрос, из-за этого выводит ошибку.

    PHP:
    1. $relation = \App\Services\Image::find($idNewImage);
    2.      
    3. dd($relation->categories()->attach($idNewImage, $categories));
    Надо что бы был примерно такой запрос

    Код (Text):
    1. insert into `category_image` (`category_id`, `image_id`) values ( 2, 18)
    И получается, если надо будет добавить во многие категории, то должно быть несколько запросов?
    --- Добавлено ---
    То что выводит null, кажись это работает.
    --- Добавлено ---
    Короче вот решение, которое должно быть

    PHP:
    1. public function store(Request $request)
    2.     {
    3.        $rules = [
    4.            'description' => 'min:4',
    5.            'image' => 'required|image|mimes:jpg,jpeg,png',
    6.            'choose-category' => 'array|required'
    7.            ];
    8.    
    9.         $messages = [
    10.             'description.min' => 'Название должно содержать минимум :min символа.',
    11.             'image.required' => 'Изображение загружать обязательно.',
    12.             'image.image' => 'Вы загрузили не изображение.',
    13.             'image.mimes' => 'Допустимые форматы: jpg, jpeg, png.',
    14.             'choose-category.required' => 'Выберите категорию'
    15.          ];
    16.    
    17.         Validator::make(
    18.             $request->all(),
    19.             $rules ,
    20.             $messages
    21.               )->validate();
    22.    
    23.       $image = $request->file('image');
    24.      
    25.       $description = $request->input('description');
    26.      
    27.       $this->imageClass->add($image, $description);
    28.  
    29.       $this->imageClass->save();
    30.  
    31.       $idNewImage = $this->imageClass->id;
    32.       $categories = $request->input('choose-category');
    33.      
    34.       $relation = \App\Services\Image::find($idNewImage);
    35.        
    36.       $relation->categories()->attach($categories);
    37.      
    38.       //$this->imageClass->addRelation($categories, $idNewImage);
    39.        
    40.       return redirect('/');
    41.     }
    --- Добавлено ---
    оказывается всё так просто
     
  20. Dimon2x

    Dimon2x Старожил

    С нами с:
    26 фев 2012
    Сообщения:
    2.199
    Симпатии:
    184
    Как получить доступ к #original?

    PHP:
    1. Master {#1018 ▼
    2.  #connection: "mysql"
    3.  #table: null
    4.  #primaryKey: "id"
    5.  #keyType: "int"
    6.  +incrementing: true
    7.   #with: []
    8.  #withCount: []
    9.  #perPage: 15
    10.  +exists: true
    11.   +wasRecentlyCreated: false
    12.   #attributes: array:3 [▼
    13.    "id" => 2
    14.     "specialization" => "Гипсокартон"
    15.     "countMaster" => 1
    16.   ]
    17.   #original: array:4 [▼
    18.    "id" => 2
    19.     "specialization" => "Гипсокартон"
    20.     "pivot_category_letter_id" => 4
    21.     "pivot_master_id" => 2
    22.   ]
    23.   #changes: []
     
  21. romach

    romach Старожил

    С нами с:
    26 окт 2013
    Сообщения:
    2.904
    Симпатии:
    719
  22. Dimon2x

    Dimon2x Старожил

    С нами с:
    26 фев 2012
    Сообщения:
    2.199
    Симпатии:
    184
    Вывожу количество комментов.

    В модели постов создал метод

    PHP:
    1.  public function comments()
    2.     {
    3.         return $this->hasMany('App\Comment', 'post_id', 'id');
    4.  
    5.     }
    В шаблоне, начинается цикл статей, в каждом цикле пишу

    PHP:
    1. <div class="comments">
    2.                         <a href="/post/{{$post->id}}">{{$post>comments->count()}} комментариев</a>
    3.                     </div>
    Теперь решил добавить этот метод, к общей выборке

    PHP:
    1. $allPosts = Posts::with(''users')
    2.                ->with('comments')
    3.                ->paginate(5);
    4.                
    И в шаблоне ничего менять не пришлось.

    Так как теперь это работает? Делает 1 запрос за раз или при каждом цикле?

    Раньше было так


    PHP:
    1. $allPosts = Posts::with(''users')
    2.                ->paginate(5);
    3.                
     
  23. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.553
    Симпатии:
    1.754
    Пара вопросов:
    • Для чего делается вызов with()?
    • Что ты получаешь, если имя связи используешь без скобок, запрос или коллекцию?
    --- Добавлено ---
    https://github.com/barryvdh/laravel-debugbar - про эту штуку в курсе? Все запросы к БД тебе покажет
     
  24. Dimon2x

    Dimon2x Старожил

    С нами с:
    26 фев 2012
    Сообщения:
    2.199
    Симпатии:
    184
    @mkramer почитал и понял, что with выбирает все данные из таблицы, это как альтернатива SELECT * ?
    --- Добавлено ---
    Когда обращаюсь без скобок, то получаю коллекцию, а со скобками объект, название связи и в нём что-то лежит, в том числе и коллекция, которая присоединилась.
     
  25. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.553
    Симпатии:
    1.754
    Аж две :) Нет, коллекцию ты не получаешь, ты получаешь, объект Relation, который является особой надстройкой на Builder-ом Eloquent
    Прочитать может и прочитал, а не понял нифига :) with заставляет Eloquent получить сразу все связанные данные для всей коллекции результатов запроса, и потом раскидать по моделям. Таким образом количество запросов сокращается. И в доке этот момент очень подробно разобран
     
    Dimon2x нравится это.