Laravel по-русски

Русское сообщество разработки на PHP-фреймворке Laravel.

Ты не вошёл. Вход тут.

#1 22.04.2017 18:36:42

Как передать в вид данные из двух связанных моделей?

Есть таблица юзеров

Schema::create('users', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name',20);
            $table->integer('image_id')->unsigned()->nullable();

            $table->foreign('image_id')
                ->references('id')->on('file')
                ->onUpdate('cascade')->onDelete('cascade');
        });

И изображений

Schema::create('file', function (Blueprint $table) {
            $table->increments('id');
            $table->string('link', 255);
        });

"link" содержит в себе записи вида "kartinka.jpg".
Хочу вывести таблицу вида пользователь-картинка
Модель пользователя

protected $fillable = [
        'name', 'image_id'
    ];

Модель файла(картинки)

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

Метод

$users = User::orderBy('id','DESC')->paginate(5);
        return view('admin.users.index',compact('users'))
            ->with('i', ($request->input('page', 1) - 1) * 5);

Вид

@foreach ($users as $user)
            <tr>
                <td>{{ ++$i }}</td>
                <td>{{ $user->name }}</td>
                <td>{{ //вывести картинку// }}</td>
            </tr>
        @endforeach

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

Не в сети

#2 22.04.2017 18:44:36

Re: Как передать в вид данные из двух связанных моделей?

При такой структуре у каждого юзера будет только одно изображение, причем твоей БД пользователь принадлежит изображению (немного странное решение). Добавь отношение в модели User:

public function file()
{
    return $this->belongsTo(File::class);
}

Пользователей загружаешь сразу с изображениями:

User::with('file')
    ->latest()
    ->paginate(5);

Выводишь так:

<td>{{ $user->file->link }}</td>

Изменено AlexeyMezenin (22.04.2017 19:49:04)

Не в сети

#3 22.04.2017 19:05:43

Re: Как передать в вид данные из двух связанных моделей?

AlexeyMezenin пишет:

При такой структуре у каждого юзера будет только одно изображение, причем твоей БД пользователь принадлежит изображению (немного странное решение). Добавь отношение в модели User:

public function file()
{
    return $this->belongsTo('File::class');
}

Пользователей загружаешь сразу с изображениями:

User::with('file')
    ->latest()
    ->paginate(5);

Выводишь так:

<td>{{ $user->file->link }}</td>

Trying to get property of non-object
При том, что var_dump ($users) выводит массив с нужными данными

Изменено Tarasovych (22.04.2017 19:07:45)

Не в сети

#4 22.04.2017 19:26:20

Re: Как передать в вид данные из двух связанных моделей?

Покажи что выдает dd($users)

Не в сети

#5 22.04.2017 19:28:22

Re: Как передать в вид данные из двух связанных моделей?

AlexeyMezenin пишет:

Покажи что выдает dd($users)

LengthAwarePaginator {#272 ▼
  #total: 2
  #lastPage: 1
  #items: Collection {#273 ▼
    #items: array:2 [▼
      0 => User {#270 ▶}
      1 => User {#271 ▶}
    ]
  }
  #perPage: 5
  #currentPage: 1
  #path: "http://site/admin/users"
  #query: []
  #fragment: null
  #pageName: "page"
}

апд:
массив пользователя

...
0 => User {#270 ▼
        #fillable: array:9 [▶]
        #hidden: array:2 [▶]
        #connection: null
        #table: null
        #primaryKey: "id"
        #keyType: "int"
        #perPage: 15
        +incrementing: true
        +timestamps: true
        #attributes: array:14 [▶]
        #original: array:14 [▶]
        #relations: array:1 [▶]
        #visible: []
        #appends: []
        #guarded: array:1 [▶]
        #dates: []
        #dateFormat: null
        #casts: []
        #touches: []
        #observables: []
        #with: []
        #morphClass: null
        +exists: true
        +wasRecentlyCreated: false
      }

Изменено Tarasovych (22.04.2017 19:29:12)

Не в сети

#6 22.04.2017 19:38:18

Re: Как передать в вид данные из двух связанных моделей?

Tarasovych пишет:
AlexeyMezenin пишет:

Покажи что выдает dd($users)

LengthAwarePaginator {#272 ▼
  #total: 2
  #lastPage: 1
  #items: Collection {#273 ▼
    #items: array:2 [▼
      0 => User {#270 ▶}
      1 => User {#271 ▶}
    ]
  }
  #perPage: 5
  #currentPage: 1
  #path: "http://site/admin/users"
  #query: []
  #fragment: null
  #pageName: "page"
}

апд:
массив пользователя

...
0 => User {#270 ▼
        #fillable: array:9 [▶]
        #hidden: array:2 [▶]
        #connection: null
        #table: null
        #primaryKey: "id"
        #keyType: "int"
        #perPage: 15
        +incrementing: true
        +timestamps: true
        #attributes: array:14 [▶]
        #original: array:14 [▶]
        #relations: array:1 [▶]
        #visible: []
        #appends: []
        #guarded: array:1 [▶]
        #dates: []
        #dateFormat: null
        #casts: []
        #touches: []
        #observables: []
        #with: []
        #morphClass: null
        +exists: true
        +wasRecentlyCreated: false
      }

В

#attributes

есть нужный

image_id

Не в сети

#7 22.04.2017 19:38:27

Re: Как передать в вид данные из двух связанных моделей?

Интересно посмотреть как раз relations, там должен быть объект file

Не в сети

#8 22.04.2017 19:39:16

Re: Как передать в вид данные из двух связанных моделей?

AlexeyMezenin пишет:

Интересно посмотреть как раз relations, там должен быть объект file

"file" => null
Ага..

Не в сети

#9 22.04.2017 19:43:12

Re: Как передать в вид данные из двух связанных моделей?

Если не у всех пользователей есть изображение, то добавь проверку:

<td>{{ is_null($user->file) ? 'no image' : $user->file->link }}</td>

Или то же самое, но с помощью @if

Не в сети

#10 22.04.2017 19:45:39

Re: Как передать в вид данные из двух связанных моделей?

AlexeyMezenin пишет:

Если не у всех пользователей есть изображение, то добавь проверку:

<td>{{ is_null($user->file) ? 'no image' : $user->file->link }}</td>

Или то же самое, но с помощью @if

Ну у меня чистая БД, я создал 2 пользователя, судя по БД, изображение у них есть, оно есть так же в файлах проекта. Возможно, проблема в контроллере. Название изображения, идентичное файлу на сервере хранится в поле "link" в таблице "file"

Изменено Tarasovych (22.04.2017 19:47:45)

Не в сети

#11 22.04.2017 19:47:53

Re: Как передать в вид данные из двух связанных моделей?

А, у тебя ключ не соответствует отношению, поэтому нужно его вручную добавить:

public function file()
{
    return $this->belongsTo(File::class, 'image_id');
}

Еще кавычки убрать нужно в File:class. Или использовать 'App\File' вместо File:class

Если таблица называется file, а не files, то нужно еще добавить в модель File:

protected $table = 'file'

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

Изменено AlexeyMezenin (22.04.2017 19:51:41)

Не в сети

#12 22.04.2017 19:53:01

Re: Как передать в вид данные из двух связанных моделей?

AlexeyMezenin пишет:

А, у тебя ключ не соответствует отношению, поэтому нужно его вручную добавить:

public function file()
{
    return $this->belongsTo(File::class, 'image_id');
}

Спасибо! Работает! Сейчас выводит просто название файла.
Сделал вот так:

<td>{{ Html::image('images/' . $user->file->link) }}</td>

Не в сети

#13 22.04.2017 19:54:56

Re: Как передать в вид данные из двух связанных моделей?

AlexeyMezenin пишет:

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

Не нашел в документации.. Можно ссылку?

Не в сети

#14 22.04.2017 19:58:11

Re: Как передать в вид данные из двух связанных моделей?

Тут одной ссылкой не отделаешься, нужно прочитать всю документацию. Договоренности есть везде - в моделях, маршрутах, контроллерах и пр. Начни с чтения доков об Eloquent и отношениях:

https://laravel.ru/docs/v5/eloquent
https://laravel.ru/docs/v5/eloquent-relationships

Не в сети

#15 22.04.2017 20:46:15

Re: Как передать в вид данные из двух связанных моделей?

AlexeyMezenin пишет:

Тут одной ссылкой не отделаешься, нужно прочитать всю документацию. Договоренности есть везде - в моделях, маршрутах, контроллерах и пр. Начни с чтения доков об Eloquent и отношениях:

https://laravel.ru/docs/v5/eloquent
https://laravel.ru/docs/v5/eloquent-relationships

Еще вопрос вдогонку: вышеприведенным способом можно (и нужно?) выводить, к примеру, авторов статьи (на такой же странице, где статей много, и возле каждой нужно указать автора) и т. д.?

Не в сети

#16 23.04.2017 07:51:34

Re: Как передать в вид данные из двух связанных моделей?

Tarasovych пишет:

Еще вопрос вдогонку: вышеприведенным способом можно (и нужно?) выводить, к примеру, авторов статьи (на такой же странице, где статей много, и возле каждой нужно указать автора) и т. д.?

Да, также выводишь. Сначала "жадно загружаешь" отношения, потом также выводишь. Если связь не belongsTo(), т.е., например, нужно вывести все книги одного автора, тогда нужно перечислять при выводе:

@foreach ($users as $user)
    Author: {{ $user->name }}
    @foreach ($user->books as $book)
        {{ $book->title }}
    @endforeach
@endforeach

Не в сети

Подвал раздела