M
M
Maxim Spiridonov2014-12-13 15:22:53
MySQL
Maxim Spiridonov, 2014-12-13 15:22:53

Is the One-to-Many relationship correct?

Laravelers, save! I've been fiddling with a one-to-many ORM relationship for an hour now, but I still don't understand why the following error occurs:

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

We need to get all the user 's sites from the sites table , where the owner column will be equal to the login of the authorized user ( the users table ) . I created a short function in the User
model (I'm trying to make the following query select * from sites where owner = the login is authorized by the user):
public function short(){
        return $this->hasOne('Site', 'owner');
    }

In CabinetController 'e I'm trying to display this thing:
public function Index(){
        
        if(Auth::check()) {
            return View::make('cabinet')->with('sites', Auth::user()->short()->getResults());
        }else{
            return View::make('cabinet.guest');
        }
    }

Well, the markup with foreach, which is in the cabinet template:
@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

I also tried to check what comes from the database as follows, but unfortunately it is empty (:
return Auth::user()->short()->getResults();

Answer the question

In order to leave comments, you need to log in

2 answer(s)
M
miki131, 2014-12-13
@miki131

Speak One to Many, Write One to One

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

G
GoodBoy123, 2014-12-16
@GoodBoy123

If using the login and owner columns is not something 100% necessary, I would do so. The text of the scripts is not complete, only the necessary parts.
Mysql:
Users table:
id,login Sites
table:
id, users_id,url,title
Laravel
Models:
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 is responsible for showing the page as a guest or user, if the pages are very different, I would separate them at the route level):
@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

I sketched it quickly, there may be typos, and a lot can change during the refactoring process.
If you use the login and owner keys, then :
Users:
public function sites(){
        return $this->hasMany('Site', 'owner', 'login');
}

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

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question