Laravel display a relationship data with soft delete - php

I want to display the name of the user in the blade using Eloquent: Relationships. My code's can display data using relationship but if the data is soft deleted it gives me a error.
Here's my code.
// History Model//
public function user()
{
return $this->belongsTo(User::class);
}
// User model //
public function history()
{
return $this->hasMany(History::class);
}
// Controller //
public function index()
{
$histories = History::find(3);
return view('booking.backend.content.history.index', compact('histories'));
}
// index.blade //
{{$history->user->name}}

I already fixed it.
In my model history I add withtrashed.
public function history()
{
return $this->hasMany(History::class)->withTrashed();
}

Related

Relationship between laravel models does not work

I have 2 models: one for users and one for clients. A user is a customer
User has a 'codigocli' field and client has a 'codigo' field
The relationships between my models are like this:
//User model
public function cliente()
{
return $this->hasOne(Cliente::class, 'codigo', 'codigocli');
}
//Cliente model
public function user()
{
return $this->belongsTo(User::class, 'codigocli', 'codigo');
}
My database is fine (I think) client has the 'codigo' field and users has the 'codigocli' field. So what am I doing wrong? When I want to query my home.blade.php with dd(auth()->user()-cliente()) I don't get anything, although it shows me the parent object fine.
H
You have an OneToOne relationship here so try this if you don't change id name:
//User model
public function cliente()
{
return $this->hasOne(Cliente::class, 'codigocli');
}
//Cliente model
public function user()
{
return $this->belongsTo(User::class, 'codigocli');
}
if you change id name:
//User model
public function cliente()
{
return $this->hasOne(Cliente::class, 'codigocli','local_id_name' );
}
//Cliente model
public function user()
{
return $this->belongsTo(User::class, 'codigocli', 'local_id_name');
}

Cannot access Intermediate table in HasManyThrough relationship

My DB schema looks like this.
Now, in artisan tinker mode, When I try to query Details table from user Model, it shows me the records of the details table but I cannot access the the Cases Model for some reason, it always returns NULL in tinker.
This is my User Model
public function details()
{
return $this->hasManyThrough('App\Models\Detail', 'App\Models\Cases', 'user_id', 'case_id', 'id', 'id');
}
What am I doing wrong?
If for convenience you want to access Details directly from the User model then you can define relations as - (may seem like a little duplication but worth if it results in ease)
class User extends Model
{
public function cases()
{
return $this->hasMany(Case::class);
}
public function details()
{
return $this->hasManyThrough(Detail::class, Case::class);
}
}
class Case extends Model
{
public function details()
{
return $this->hasMany(Detail::class);
}
public function user()
{
return $this->belongsTo(User::class);
}
}
class Detail extends Model
{
public function case()
{
return $this->belongsTo(Case::class);
}
}
Now both cases and details can be directly accessed via User record
$user->cases;
$user->details;
The idea of hasManyThrough is to skip the intermediate table. If you need to look at the cases and the details maybe you should define other relations for it.
// User model
public function cases()
{
return $this->hasMany(Cases::class, 'user_id');
}
// Cases model
public function details()
{
return $this->hasMany(Detail::class, 'user_id');
}
$users = User::with('cases.details')->get();
foreach ($users as $user) {
// an user
foreach ($user->cases as case) {
// a case
foreach ($case->details as $detail) {
// the details of a case
}
}
}

Delete record from one-to-many relationship

I have 3 tables:
users
id
role
email
typable_id
typable_type
buyers
id
name
address
avatar
email
residential_id
residentials
id
name
city
state
And here is my model that shows the relationship
User.php
public function typable()
{
return $this->morphTo();
}
Buyer.php
public function residential()
{
return $this->belongsTo(Residential::class);
}
public function user()
{
return $this->morphMany(User::class, 'typable');
}
Residential.php
public function buyer()
{
return $this->hasMany(Buyer::class);
}
If I want to delete the residential, all buyers from that residential need to be deleted. Same as users need to be deleted too when the buyers is deleted. How can I do that? This is what insides my Residential Controller for destroy function.
ResidentialController
public function destroy(Request $request)
{
$residentials = Residential::find($request->input('id'));
$residentials->id = $request->input('id');
$residentials->name = $request->input('name');
$residentials->delete($residentials);
return response()->json($residentials);
}
I have tried to put this code to delete the buyers (for users not yet) inside destroy() but nothing is changed for the buyers to be deleted.
$buyers = Buyer::where('residential_id','=',$request->residential_id)->first(); $buyers->delete($buyers);
While this is the code that I managed to do if I want to delete the buyers, the users are deleted too.
BuyerController
public function destroy(Request $request)
{
$users = User::where('email', '=', $request->email)->first();
$buyers = Buyer::find($request->input('id'));
$buyers->id = $request->input('id');
$buyers->name = $request->input('name');
$buyers->delete($buyers);
$users->delete($users);
return response()->json($buyers);
}
I hope there is someone to help and teach me the correct way.
Approach-1
you can override the delete function for any model.
//Residential.php
public function delete()
{
$this->buyer->delete();
return parent::delete();
}
//Buyer.php
public function delete()
{
$this->user->delete();
return parent::delete();
}
Now when you delete any Residential record, the chain will first delete any related user and then delete buyer and finally delete the Residential record.
Approach-2
You can use each() method to get all relating buyer and then get all relating user.
$residentials->buyer
->each(function ($b) {
$b->user->each(function ($u) {
$u->delete();
});
$b->delete();
});
$residentials->delete();
You might want to register model events to handle that:
class Residential extends Model
{
// Lets use plural form for a HasMany relationship.
public function buyers()
{
return $this->hasMany(Buyer::class);
}
protected static function booted()
{
static::deleting(function ($user) {
// I am using Higher Order Message, check this out: https://laravel.com/docs/8.x/collections#higher-order-messages
$this->buyers->each->delete();
});
}
}
class Buyer extends Model
{
// Lets use the plural form for a MorpMany relationship.
public function users()
{
return $this->morphMany(User::class, 'typable');
}
protected static function booted()
{
static::deleting(function ($user) {
$this->users->each->delete();
});
}
}
And you only have to remove a single object in your controller:
class ResidentialController
{
public function destroy(Request $request)
{
$residential = Residential::findOrFail($request->input('id'));
$residential->delete();
// The framework is gonna automatically convert this to a JSON object.
return $residential;
}
}
class BuyerController
{
public function destroy(Request $request)
{
$buyer = Buyer::findOrFail($request->input('id'));
$buyer->delete();
// The framework is gonna automatically convert this to a JSON object.
return $buyer;
}
}

Laravel 5 push() not saving hasOne relationship

In my destroy function of my controller, I'm attempting to take a copy of my object (model with one relationship) and insert it into another database before deleting it. However only the model is being created and not the relationship. Why is this happening?
Destroy function:
public function destroy($id)
{
$user = User::with('Phone')->find($id);
$archive = $user->replicate();
$archive ->changeConnection('mysql2');
$archive ->push();
}
User model:
public function phone()
{
return $this->hasOne('App\Phone');
}
Phone model:
public function user()
{
return $this->belongsTo('App\User');
}
When I insert via the store function in my controller, it sets up the relationship just fine:
public function store(Request $request)
{
// Validation has passed, insert data into database
$user= User::create($request->all());
$user->Phone()->create($request->all());
}

Laravel 4:: Returning models and its relationship

I would like to return the model and part of its relationship
EX::
User model
public function comments()
{
return $this->hasMany('comments');
}
Comments model
public function user()
{
return $this->belongsTo('user');
}
Can I return all comments and the user's name associated with the comment?
The desired effect is
$comment = Comments::find($id);
$comment->user;
return $comment;
This will return the one comment and the associated user full model. I just need the name of the user. And this does not works if I call Comments::all()
Thank you in advance.
You're looking for Eloquent's Eager Loading
Assuming your Comments model has a method user():
public function user()
{
return $this->belongsTo('User');
}
You should be able to do this in your controller:
$comments = Comments::with('user')->where('post_id', $post_id);
// Return JSON, as is Laravel's convention when returning
// Eloquent model directly
return $comments;
You can do the opposite as well:
Assuming your User model has a method 'comments()', like so:
public function comments()
{
return $this->hasMany('Comment');
}
Inside of your controller, you should be able to do the following, assuming your have the $id of the user available:
$user = User::with('comments')->find($id);
// Return JSON, as is Laravel's convention when returning
// Eloquent model directly
return $user;

Categories