Loading relation of new model in Laravel - laravel

I just want to get hasOne relation of New model.
Can I load it before I will save it.
I have $user = new User(['order_id' => $order_id]);
How can I get $user->order; without build new request?

As others have already pointed out the model must be saved before retrieving any relations.
My usual approach for this is using lazy eager loading:
// Create new model with data
$newModel = Model::create([
'column' => $value
]);
// Use load to retrieve any relations
return $newModel->load('myRelationship');

Related

How to save associations on an instantiated object

How do I associate other associations before saving "parent"? I have a car that have many other parts:
A car has many seats
A car has many floor mats
A car has one mirror
etc.
The thing is, if either the seats or floor mats has any defects then the car cannot be created:
$car = new Car(...);
// Many mats
$mats = [new Mat(..), new Mat(..)];
// One mirror
$mirror = new Mirror(..);
// I need to put them all together.
// This does not work
$car->saveMany([$mats, $mirror, $mats]);
// Does not work
$car->mats()->saveMany($mats);
$car->associate($mirror);
// Car should not be saved if either any of its associations have an error.
$car->save();
The docs mentioned nothing about this example when instantiating a new object then save its associations: HasMany, HasOne, BelongsTo etc
I've looked at these but cannot get my head around it:
Saving related records in laravel
Eloquent push() and save() difference
One To Many associate
How to "associate" "car's" associations by calling "save()"?
I would suggest that you look into the validation functionallities of laravel. (https://laravel.com/docs/8.x/validation)
you can make nested validations, so for example if you want to validate the seats of a car you can make rules like this:
public function store(Request $request)
{
$validated = $this->validate($request, [
'name' => 'required|string',
'model' => 'required|exists:car_models,name',
'seats' => 'required|array',
'seats.*.color' => 'required',
'seats.*.width' => 'numeric',
'seats.*.fabric' => 'required|string',
]);
// create the car with all relation data
return $car;
}
The validation could be done as shown above, or via form request validation (https://laravel.com/docs/8.x/validation#form-request-validation).
That way, you can be sure that the users input is valid and will work before any of the models are created. After that you should create the car and add all the relations after. I would however suggest that you use the eloquent relations instead, by doing that you can write something like
// Create relation model with array of data
$car->seats()->create($seatData);
// Create relation models with collection of data
$car->seats()->createMany($seatsDataCollection);

Laravel create multiple records in one query with Eloquent and get the created models

I know I can do the following to create multiple records with one query :
$users = [];
$users[] = ['name' => 'Tom'];
$users[] = ['name' => 'Jerry'];
$result = User::insert($users);
The problem of this approach is that ìnsert uses the query builder, and returns a boolean.
What if I wanted to have the created Eloquent models returned ? Would that be possible without having to do another query to retrieve them (how would I do that since I don't know the created ids ?) ?
I'm looking for something like the create method (which returns the created User model), but for multiple inserts (afaik createMany does not work outside of relationships)
Thanks

insert data to a migration without a model

How to insert data to a migration (table) without a model in Laravel, a migration with its model in which I define the corresponding relationships and the other only the migration
It can clearly be done according to the documentation of Laravel when you have the migration with your respective model, as follows.
$comment = new App\Comment(['message' => 'A new comment.']);
$post = App\Post::find(1);
$post->comments()->save($comment);
or
$post = App\Post::find(1);
$comment = $post->comments()->create([
'message' => 'A new comment.',
]);
This works for me only when I have with their respective models but not as I want to do
I am pending if someone can clarify with this
You can interact with database directly without a model using the DB facade:
DB::table('tablename')->insert(['column'=>'value']);
Same way you can use wheres, selects. For more details see Laravel docs - Database: Query Builder - Inserts

Bulk insertion of array of eloquent models

Is it possible to insert several eloquent models in one query?
Let's say I have eloquent model Page and I want to insert array of pages or collection of pages in one query
$page1 = new Page();
$page2 = new Page();
$pages = [
$page1,
$page2,
];
or
$pages = Collection([$page1, $page2]);
I want something like
$pages->save();
But it warns that "Method save does not exist".
I saw this, but there they insert array of arrays and I want to insert array of eloquent models.
You could try the saveMany() option.
This example might work for you:
DB::table('pages')->saveMany($pages);
And if you are working with relationships you can even use a "cleaner" way (just showing you example of ways to use this function):
$book = App\Book::find(1);
$book->pages()->saveMany([
new App\Page(['title' => 'A new page.']),
new App\Page(['title' => 'Another page.']),
]);

Can you create a new Model instance without saving it to the database

I want to create a whole bunch of instances of a model object in Laravel, then pick the optimal instance and save it to the database. I know that I can create an instance with Model::create([]), but that saves to the database. If possible I'd like to create a bunch of models, then only "create" the one that is best.
Is this possible?
I am using Laravel 5.0
You create a new model simply by instantiating it:
$model = new Model;
You can then save it to the database at a later stage:
$model->save();
You can create instances with Model::make(). It works the same way as create but it doesn't save it.
Whether or not this is best practice is another matter entirely.
Yes, it is possible different ways: you can use the mass assignment without saving.
Please remember to set first the $fillable property in your model.
WAY #1: using the method fill
$model = new YourModel;
$model->fill([
'field' => 'value',
'another_field' => 'another_value'
]);
$model->save();
WAY #2: using the constructor
$model = new YourModel([
'field' => 'value',
'another_field' => 'another_value'
]);
$model->save();
In YourModel set the $fillable property with the fileds allowed for mass assignment:
class YourModel extends Model
{
protected $fillable = ['field', 'another_field'];
// ...
}
Laravel documentation: https://laravel.com/docs/9.x/eloquent#mass-assignment
there is also a method you can call it statically to get new instance:
$modelInstance = $modelName::newModelInstance();
it takes array $attributes = [] as a parameter

Resources