Правильно ли составлено отношение «Один ко многим»?

Ларавельщики, спасайте! Вожусь с отношение ORM "один ко многим" уже час, но так и не понял, почему возникает следующая ошибка:

Invalid argument supplied for foreach() (View: C:\xampp\htdocs\lar.ru\app\views\cabinet.blade.php)


Нужно достать все сайты пользователя из таблицы sites, где колонка owner будет равна логину авторизованного пользователя (таблица users) .

Я в моделе User создал функцию short (Я пытаюсь сделать следующий запрос select * from sites where owner = логину авторизовано юзера):

public function short(){
        return $this->hasOne('Site', 'owner');
    }


В CabinetController'e пытаюсь это дело вывести:

public function Index(){
        
        if(Auth::check()) {
            return View::make('cabinet')->with('sites', Auth::user()->short()->getResults());
        }else{
            return View::make('cabinet.guest');
        }
    }


Ну и разметочка с foreach, которая находится в шаблончике cabinet:

@foreach($sites as $site)

        <ul>
            <li>url: {{ $site->url }}</li>
            <li>title: {{ $site->title }}</li>
            <li>description: {{ $site->description }}</li>
            <li>keywords: {{ $site->keywords }}</li>
        </ul>

    @endforeach


Так же пробовал проверять то, что приходит из базы следующим образом, но к сожалению там пусто(:

return Auth::user()->short()->getResults();
  • Вопрос задан
  • 2402 просмотра
Пригласить эксперта
Ответы на вопрос 2
@miki131
Говорите "Один ко многим", а пишите "Один к одному"
public function short () {
		return $this->hasMany('Site', 'owner', 'login');
	}
Ответ написан
@GoodBoy123
Если использование колонок login и owner не является чем-то 100% необходимым, я бы сделал так. Текст скриптов не полный, только нужные части.

Mysql:
Таблица users:
id,login

Таблица sites:
id, users_id,url,title

Laravel
Модели:
Users:
public function sites(){
        return $this->hasMany('Site');
}


Site:
public funtion user() {
	return $this->belongsTo('User');
}


CabinetController:
// Используем IOC контейнер, чтобы в будущем было легче тестировать, также строка
// $this->userManager->getSites() гораздо более понятна через 3 месяца, чем
// Auth::user()->short()->getResults()

use Acme\UserManager as UserManager;

protected $userManager;

public function __construct(UserManager $userManager) {
	$this->userManager = $userManager;
}

public function index(){
            return View::make('cabinet')->with('sites', $this->userManager->getSites());
    }


Acme\UserManager:
public function getSites() {
	
	if (Auth::check()) {
		return User::find( Auth::id() )->sites()->get();
	}

	return false;
}


cabinet.blade.php (За показ страница в виде для гостя или пользователя, отвечает View, если страницы очень разные, я бы разделил их на уровне route):

@if($sites)
@foreach($sites as $site)

        <ul>
            <li>url: {{ $site->url }}</li>
            <li>title: {{ $site->title }}</li>
            <li>description: {{ $site->description }}</li>
            <li>keywords: {{ $site->keywords }}</li>
        </ul>

@endforeach
@elseif
<p>Войдите, чтобы пользоваться сервисом</p>
@endif


Набросал по быстрому, могут быть опечатки, также в процессе рефакторинга многое может меняться.

Если же использовать ключи login и owner, то :

Users:
public function sites(){
        return $this->hasMany('Site', 'owner', 'login');
}


Site:
public funtion user() {
	return $this->belongsTo('User' , 'owner', 'login');
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы