Laravel - Check & Make eager load of relational model. - php

I'am trying to check if the record has relation and at the same time I want to make an eager load so:
User::has('item')->with('item')->get();
I've noticed that with method do not check if the record has a relation, is this the right sequence or there are a shorter way to code this?

Just try this:
// Pull all blog users that have
// at least one related model/item
$users = User::has('item')->get();
Instead of this:
User::has('item')->with('item')->get();
Reference on Laravel website.

Related

How can I handle fake 1-n relationship in Laravel Backpack?

I have an old db under my application where not all relations are actually SQL relations, but some of them are stored in a string column.
Ex.
Tables: Tags, Articles
Table Articles has 'tags_ids' column where I have '33;44;82;' (the tag ids)
I would like to know if I can use the Laravel Backpack relationships UI with this kind of data.
I surely will have to "mutate" the data during the get and the set, but I can't find a way to do it.
I dont think laravel supports something like that directly as a relationship.
You could certainly write a custom column template in backpack that would explode $entry->tags_ids on ;, query Tags for those ids and then display them in a loop.
That said, IMHO, you'd be much better of adding an intermediate table like article_has_tag to map your tags and articles properly, then you could use all the built in features of laravel and backpack normally. If you still need the old application to work with the original data structure, you could write an "after insert/update" trigger for the articles and article_has_tag tables to keep them in sync (being careful to not cause an infinite loop of course).

What's the best practice of creating models and getting the information using the Laravel Eloquent?

I'd like to know what is the best way of creating models using the Laravel framework? As far as I know, the model is used for the connection to the DB table and then, you can do whatever you want with its data.
Creating a new model per DB table (as stated here) isn't good and models should be created per business object. Not sure what it means. I'd like to access the same table and get some information from it using the Eloquent, so similar to this:
<?php
// Get the model class
use App\Post;
// Grab some data from the posts table
$posts = Post::all();
But it requires having a model. Using the select method, e.g.:
$posts = DB::table('posts')->select('title, body')->get();
Doesn't require having a model so I don't quite understand what's the point of models? I couldn't find enough information inside the Laravel docs: https://laravel.com/docs/5.6/eloquent.
As a full explanation of your question:
Using method:
<?php
// Get the model class
use App\Post;
// Grab some data from the posts table
$posts = Post::all();
will be the same as running a query like:
<?php
$posts = DB::table('posts')->select('*')->get();
but the biggest difference is that the first returns an Eloquent object, while the later returns a normal object. The first model requires a model, which extends eloquent, the later method is using the DB class, which does not extend eloquent. So when you want to use Eloquent you would have to use models.
Creating a new model per DB table (as stated here) isn't good and models should be created per business object. Not sure what it means.
Entities are things like Users, Posts, Comments, messages, but not relation tables such as user_has_posts or user_has_messages. Not entirely sure how else to explain it, but i'm sure you will get the idea.
Also keep in mind, models are supposed to only contain database logics, I've seen it plenty of times where people use models to filter arrays but this should not belong to models.

Basic Eloquent Relationship Enquiry - One to One

**USER MODEL**
public function post(){
return $this->hasOne('App\Post','user_id','id');
}
**WEB ROUTE**
use App\User;
Route::get('/{id}/post',function($id){
return User::find($id)->post;
});
Hi everyone, I'm fairly new to both PHP and Laravel and have been struggling a bit. I just have 2 questions for this code.
In the web routes, why doesn't post have any () beside it? It was declared a function in the user model. And.. I am unsure of how these relationships work (correct me if I am wrong) but does the code above look for a user with a specific $id and connects it with a post having a similar $user_id value?
For the first bit, it is a dynamic property, here you can find how you can actually make one yourself Laravel: create a dynamic property. They essentially work because the result is a single object search based on the id, since it doesn't have to retrieve a collection it allows itself to be accessed like an attribute of the object.
And yea pretty much on the second one. It also uses laravels models to retrieve the data from the database so that you get an object back without needing to create the repositories yourself.
There are major differences between User::find($id)->post and User::find($id)->post(). First one is returning the result of the related relations so you get the post that has user_id equal to $id.
The second one returns a query builder,so you can add more conditions. For example User::find($id)->post()->where("status", 1)->get().

How do you know what fields are in a Laravel Model?

I am trying to unit test creating a company however I don't know what the fields/attributes of the model are.
So I look in App\Company.php, but there is no list of fields there.
Then I look at the migrations, but I have to go through each of them to find the fields available.
So as a last resort I open a DB explorer to find what fields are in the model.
Is there an easier way to know what fields exist in a model?
You can do it this way, without the need of loading any object from the db:
$fields = (new \App\Company())
->getConnection()
->getSchemaBuilder()
->getColumnListing((new \App\Company())->getTable());
Also you can:
$fields = Schema::getColumnListing((new \App\Company())->getTable()));
The easiest way is to use the getAttributes() method on an existing object.
This will give you all database columns of that object.
I would search for the migration of the database table (in database/migrations/). If there isnt any migration I would go for the anwser #Luceos gave.

How do I reload a relation collection in laravel?

In Laravel, after using attach() or detach() to add or remove something from a relation, the collection has not changed. So if I have a model whose relation contains [1, 2], after this:
$model->relation()->detach(1);
$model->relation()->attach(3);
it will still contain [1, 2]! How do I refresh it?
You can easily tell laravel to load a relation with a single command:
$model->load('relation');
Will tell it to refresh the relation collection, and $model->relation will now show the correct values.
Also unloading a relation will be like this:
$model->unsetRelation('relation')
either just unset it and let the system reload on demand.
unset($model->relation)
or
$model->unsetRelation('relation');
And let it be loaded on request.
From Laravel 7.x you can use $model->refresh() for refreshing the model and it's relations.
Here the docs
Conclusion: three solutions in here
$model->load('relation');
unset($model->relation);
$freshCollection = $user->roles()->get();`
It is possible to use Eloquent query builder:
$freshCollection = $user->roles()->get();
If you want to force all your relations to reload on an as-needed basis and you're inside your model, you can use:
$this->relations = [];
$model->fresh() did the job for me.
Wanted to replicate multiple levels of nested models then do a loop over them.
Laravel was caching the previous relation and not the new "current" relation.

Categories