2

I'm trying to use Eloquent with a relationship and alwys have th same result:

Call to undefined method Illuminate\Database\Query\Builder::xxxx()

where xxxx could be "sons" defined in my model or save() if I use another code.

First of all I have this two models (simplified):

<?php

use Cartalyst\Sentry\Users\Eloquent\User as SentryUserModel;

class User extends SentryUserModel {

    public static $rules =          array(  'first_name'        => 'required',
                                            'last_name'         => 'required',

    );

    protected $hidden = array('password', 'remember_token');

    public function sons()
    {
        return $this->hasMany('Son');
    }

}

and

class Son extends \Eloquent {

    protected $guarded =['id'];

    public $timestamps = false;

    public static $rules =          array(  'first_name_son'    => 'required',

    );

    public function user()
    {
        return $this->belongsTo('User');
    }

}

and PhpStrorm tolds me tha Eloquent is an undefined class. Even so, I can use some methods.

My problem now. I try tu use this to save a "son" of a "user":

$user = Sentry::getUser();
$data = Input::all();
$rules_son = Son::$rules;

$son = new Son(array(
            'first_name_son'    => $data['first_name_son'],
 ));

 $user->sons()->save($son);

here breaks with

Call to undefined method Illuminate\Database\Query\Builder::sons()

and if I use

$user->with('sons')->save($son);

Call to undefined method Illuminate\Database\Query\Builder::save()

and this works fine

Son::create(array(
            'user_id'           => $user->id,
            'first_name_son'    => $data['first_name_son'],
));

All this code is in my UsersController

What's the matter using mnethod "sons()", and why in this proyect Eloquent could be "not defined"? (it's defined becouse I can search or save using Eloquent ORM)

Thanks guys

kikerrobles
  • 2,079
  • 3
  • 16
  • 26

2 Answers2

1

While I was waiting for an answer ;), I still having problems with Eloquent methods. I cant use something as $user->books()->get() or ->attach() in a relation many to many users and books, also with User::with('books') I have the same problem

Call to undefined method Illuminate\Database\Query\Builder::xxxx()

My problem is becouse of Sentry. I get the User with:

$user = Sentry::getUser();

And, I don't know why, this $user is not a User model too, so some methods fail.

My solution, I don't know if it's the best one: - create a static function to call the user still using Sentry

//In User.php model
public  static function eloquentUser(){
    $sentry_user = Sentry::getUser();
    return $user = User::findOrFail($sentry_user->id);
}

Then I call it with:

$user = User::eloquentUser();

Stiil using Sentry and works with Eloquent.

kikerrobles
  • 2,079
  • 3
  • 16
  • 26
0

Now i think you are a bit confused here with the Query Builder. You cannot use $user->books() because books it is not a method, instead when using only books, Eloquent uses magic methods to get Model properties that means table fields or relations

When using User facade, the result will be an User Eloquent Model and by using this

$users = User::with("books")->get()

It will fetch all the users and books for each user. You can access now your books by making

$mybooks = $user->books

Which might be again an ArrayCollection of some Eloquent Model. See that get() method is specific for Query Builder and use only when trying to fetch data from Db.

Now, i didnt get the part with Sentry.

For the future here are some tips

  • User Facade is only to not need to instantiate a new object to Build a query for an specific Model, but in the end this is still a QueryBuider so it has only methods specifics for queries like "with" or "get" or "join" etc
  • Do not try to use Query Builder methods for Eloquent Model. there is no reason to do

    $user->with(books) if you already fetched books using. With method does not even exists
    User::with(books)->get() 
    
  • Save your model from model like

    $user->books->save()
    

Good luck

Kun Andrei
  • 266
  • 3
  • 8
  • Sorry, but books() it's an Eloquent method created in User model to define the relation. As you can see with methods users() and sons() in the code attached to the question. This methods are in the Laravel documentation. You are talking about Eloquent Eager Loading. It doesn't work if the methods books(), or sons() or users() aren't defined. – kikerrobles Jun 12 '15 at 09:14
  • ->save() is used to save a model, I'm saving a relation between two models in a pivot table, you must use ->attach() or ->detach(), addding save() if it's not saved. – kikerrobles Jun 12 '15 at 09:17
  • Yes @kikerrobles, but you do not need to call $user->books(), since this is called when using Facade User::with('books') and load your books inside relations property of User Eloquent Modle object. An then, when trying to access it with $user->books, it calls a magic method and fetches the relationship books. Indeed i am talking about Eloquent Eager Loading and those methods are used when loading a Relationship, they are not meant to be called from within your Eloquent Model Object like $user->books(), since it won't return or do anything :) – Kun Andrei Jun 12 '15 at 09:28
  • Hi Kun, I'm using this methods now, and they work. If I have a large base I use "with", it makes less querys. But read any documentation, this methods are defined in every model with relations, and they work, ¡sure! ;) – kikerrobles Jun 12 '15 at 20:56