I'm trying to get the data without using eager loading in a Eloquent Model but I needed to cast it into Array to use in some part of the code.
In order words, I wanna just get the data like this example:
$invoice->invoice_type_id->name;
Since it's an array what I'm writing is: nfe['invoice_type_id']['name']
But I'm getting this error (because it's an array):
Trying to get property of non object
So, my query is:
Invoice::query()->where('order_id', $order_id)->get()->toArray();
And my model I already have the relationship declared:
public function invoiceType()
{
return $this->belongsTo(InvoiceType::class);
}
Related
ErrorException:
stripos() expects parameter 1 to be string, object given
For the groupBy() call in the with() method
$user = User::with([
'pricelists' => function($query) {
$query->groupBy(function($var) {
return Carbon::parse($var->pivot->created_at)->format('m');
});
}
])->where('id', $id)->get();
I already saw a few posts talking about how to manage this problem and that it shall not be possible to use groupBy() in eloquent but I do not really understand why...
To be clear:
User and Pricelist model got a many-to-many relationship with the default timestamps() method. I am trying to get the downloaded pricelists grouped by their months they were downloaded from the current user.
After a few attempts I just deleted the above shown => function($query... statement from the with() method and just left the with(['pricelist']) to fetch all datasets and tried this:
$user->pricelists = $user->pricelists->groupBy(function($var) {
return Carbon::parse($var->pivot->created_at)->format('m');
});
return $user->pricelists;
And it works fine and returns an array with multiple arrays for each month... But returning it like this:
return $user;
returns just 1 array with all entries... I do not really get the sense behind it right now...
The two groupBy() method that you are using in the two code you provide are totally different methods.
The first groupBy() where you use it in the callback is actually being called by $query which is a query builder object. The groupBy() here is used to add SQL GROUP BY Statement into the query. And as per the documentation, it only take string variables as parameter.
The groupBy() in your second code is being called by $user->pricelists which is a laravel eloquent collection. The groupBy() method here is actually from the base collection class and is used to group the items inside the collection into multiple collections under the different key defined by the parameter passed to the function. Please read the documentation here.
For your case, the second groupBy() is the one you should be using since you plan to use a callback and will allow you to use more complicated logic.
I have a one-to-one relationship between User and UserSettings models,
But (after $user = auth()->user()) when I try $user->settings()->something it throws an Undefined property error.
It's gone when I use $user->settings()->first()->something...
My question is, is this how it's supposed to work? or am I doing something wrong?
You cannot directly run $user->settings()->something.
Because when you call $user->settings(), it just return Illuminate\Database\Eloquent\Relations\HasOne object.
So it is not the model's object, you need to take the model's object and call its attribute like this.
$user->settings()->first()->something;
Dynamic Properties
Since you have one-to-one relationship between User and UserSettings.
If you have a one-to-one relationship in your User model:
public function settings()
{
return $this->hasOne('App\Models\UserSettings', 'user_id', 'id');
}
According to Laravel doc
Once the relationship is defined, we may retrieve the related record using Eloquent's dynamic properties. Dynamic properties allow you to access relationship methods as if they were properties defined on the model:
Eloquent will automatically load the relationship for you, and is even smart enough to know whether to call the get (for one-to-many relationships) or first (for one-to-one relationships) method. It will then be accessible via a dynamic property by the same name as the relation.
So you can use eloquent's dynamic properties like this:
$user->settings->something; // settings is the dynamic property of $user.
This code will give you a result of collection.
$user->settings;
So calling 'something' is not available or it will return you of null, unless you get the specific index of it.
$user->settings()->something
while this one works because you used first() to get the first data of collection and accessed the properties of it .
$user->settings()->first()->something
The first method returns the first element in the collection that passes a given truth test
see docs here laravel docs
If you want to get the user settings itself simply do this:
$user->settings
Then you can get the fields of the settings doing this:
$user->settings->something
When you do this $user->settings() you can chain query after that. E.g.
$user->settings()->where('something', 'hello')->first()
That's why the output of $user->settings and $user->settings()->first() are the same.
Auth only gives you user info;
Try the following code:
$user = User::find(auth()->user()->id);//and then
$user->settings->something;
In my Profile model I setted this relationship
public function lease()
{
return $this->belongsTo(Lease::class, 'lease_id', 'id');
}
And in my Lease model I seeted this way
public function profile()
{
return $this->hasOne(Profile::class, 'lease_id', id);
}
As longs as I know in laravel you could do
$profile = factory(App\Profile::class)->create();
$profile->lease()->get();
And then responds correctly with the model inside of a collection
And if I do
$profile->lease
Responds correctly directly with the model
It isn't supposed that dynamic propertis execute the query right away like a shortcut of ->lease()->get()? Why it gives different formatted results?
When you are calling get on a builder you are getting a collection always. When you call first on a builder like that you will get a model or null. The dynamic property for the relationship, based upon the relationship object, will either query with get or first respectively when it loads it. Which is why $model->relationship is returning you the result you expect.
The relationships that are singular, cause a find and the ones that are many cause a get.
Laravel 5.4 - Docs - Eloquent - Relations - Relationship Methods vs Dynamic Properties
I am using eloquent model to retrieve data from database.My query
$tests_details = Previous_Mocks::where($data)->orderBy('sno', 'desc')->get();
As of my knowledge $tests_details will return array of objects(results) but when i echo is_array($tests_details) it is returning false which means it's not an array but when i echo count($test_details) it is showing the correct count.See below code
foreach ($tests_details as $td)
{
echo is_object($td);
echo "<br/>";
}
it is returing 1 for is_object($td). When i print $tests_details using print_r function below is the output i am getting
and when is echo $tests_details[0]->edate it is showing proper output and everything working fine. But i want to know why the eloquent returned the data in the format shown in image instead of normal objects. I am new to laravel and currently using laravel 5.0 any explanation is appreciable.
The data return by Previous_Mocks model is a collection object.
All multi-result sets returned by Eloquent are instances of the
Illuminate\Database\Eloquent\Collection object, including results
retrieved via the get method or accessed via a relationship. The
Eloquent collection object extends the Laravel base collection, so it
naturally inherits dozens of methods used to fluently work with the
underlying array of Eloquent models.
However, collections are much more powerful than arrays and expose a variety of map / reduce operations that may be chained using an intuitive interface.
Eloquent Collection Reference
I'm trying to get all the "books" that one user have: but I can't do it how I need.
I use the following code:
/*Gets all books from the user whose id is 1*/
$books= User::find(1)->books();
That return to me an Collection object; but I need a Builder object, as I get when I use the "select" method.
/* This code return me a "Builder" object */
Books::select(array('id', 'name', 'type'));
I need the Builder instead of Collection because I using Bllim/Datatables on my project and this package just accept a Builder object...
If I send it a Collection its throw me the next error (500 - Internal Server Error):
{
"error":
{
"type":"ErrorException",
"message":"Undefined property: Illuminate\\Database\\Eloquent\\Builder::$columns",
"file":"\/var\/www\/proyect\/myproyect\/vendor\/bllim\/datatables\/src\/Bllim\/Datatables\/Datatables.php",
"line":256
}
}
Anybody knows the solution?
EDIT:
When I use the getQuery() method twice I get the following error:
{"error":{"type":"ErrorException","message":"array_values() expects parameter 1 to be array, null given","file":"\/var\/www\/proyect\/myproyect\/vendor\/bllim\/datatables\/src\/Bllim\/Datatables\/Datatables.php","line":550}}
Is rare, because when I used the "select" method Datatables worked perfectly...
This code works:
Books::select(array('id', 'name', 'type'));
But the code you told me doesn't work:
$user = User::find(1);
$user->books()->getQuery()->getQuery();
Use method call books():
$user = User::find(1);
$user->books(); // relation object
$user->books; // dynamic property
First books() returns a relation object, that you can chain Eloquenr\Builder or Query Builder methods on.
Second books is a dynamic property - the query is automatically executed and its result is stored in the $user->relations['books'] and returned.
edit
As per comment - what you need is base Query\Builder object if you want to access columns property, so you need getQuery twice:
$user->books()
->getQuery() // get underlying Eloquent\Builder
->getQuery() // get underlying Query\Builder
->columns // public property on the above