The right way to receive related data in Laravel? - laravel

Here are some models:
UserModel
SpecializationModel
UserSpecializationModel
I need to recieve authorized user's specialization. I can do that:
$specializations = UserSpecialization::where("user_id", Auth::user()->id)->get();
Also I can do this through the UserModel model using relation hasMany() specializations().
When to use first case and the second?
$specializations = Auth::user()->specializations();
Do I need a model UserSpecializationModel?

In general you don't need UserSpecilizatonModel, in most situations you wont access data directly from that table, you'll either do it through user or specialization model.
Check also https://laravel.com/docs/9.x/eloquent-relationships#retrieving-intermediate-table-columns for accessing data from pivot table.

Related

Which relation to use in Laravel?

Which relation to use in Laravel to bind two table through third?
When Doctors can be assigned to some Centers. The intermediate table will be as:
doctor_id | center_id
How to create model in Laravel for this case?
You don't need a model for the intermediate table, simply use attach
Example:
$center = Center::create();
$doctor = Doctor::find(1);
$doctor->centers()->attach($doctor->id);
This is a very simple example but should give you the idea, of how to approach it.
All of it of course requires you have set up your Center and Doctor model with the correct many to many relations
Doctor.php model:
public function centers()
{
return $this->belongsToMany(Doctor::class);
}
See the documentation, for more information.
You could obviously create a model called DoctorsCenter and create it manually by doing this, whenever you want to attach a relation.
DoctorsCenter::create(['center_id' => $center->id, 'doctor_id' => $doctor->id]);
I don't see any good reason for doing this, and would not recommend it.
You can use hasMany or belongsTo relationship of Laravel.
See the laravel documentation, for more information

Laravel Eloquent: Access relationship of Original

In Laravel you can use getOriginal() on a model in order to get the original model (before changes since it was queried).
Now I need to access the relationship of that original model... is there a way to do that?
$item = OrderItem::where('id', $id)->with('qualification')->first();
$original_item = $item->getOriginal();
$original_item["qualification"] is not defined. I can access qualification_id though.
getOriginal() method returns array of the model's original attribute values, it is not a model itself, therefore you can not get a relationship.
So you can access the relationship using standard way: $item->qualification, that should not be affected by your changes of the parent model.

Laravel Dynamic Eager Loading for Dynamic Relationships

Laravel Version: 5.5
PHP Version: 7+
Database Driver & Version: mysql 5.7+
Scenario:
I have a SaaS application that has flexible database structure, so its fields are bound to change, especially given it has a Json field (for any extra database structure to be created from client side of the application), including relationship based fields. so Account Table can have dynamically created employee_id field, and thus the need to access relationships dynamically
Problem:
I need to EagerLoad models based on this dynamic relationship. If I had something like this:
// Account Model
public function employee(){
return $this->belongsTo(App\Employee);
}
it would be easy. But what I have is this:
public function modelBelongsTo(){
return $this->belongsTo($dynamicClassName, $dynamicForeignKey);
}
Now if I eager load this, I'll get Account Model instance with related Employee on key modelBelongsTo. This is how Eloquent Names based on the function of eagerload. But after this I cannot use this function again to eagerload a second model because it'll just overwrite results on modelBelongsTo key.
Possible Solution Directions:
1) Can I Somehow change laravel's process to use a name I provide?
or
2) Can I write functions on the fly to overcome this so I'll write employee function on the fly?
or
3) Worst Case Scenario: I iterate over all records to rename their keys individually because I am using a pagination, it wouldn't that big of a deal to loop over 10 records.
Us a morph relationship
define the various dynamic classnames say
Employee
Boss
Morph works by having the related key and the table name stored in the parent table, it means to relate them you have to use a join or an orm and you cant have foreign key constraint on it as it links to different tables.
then have your account have morphs where
we have
Account
as top class
then we have
EmployeeAccount, BossAccount
which have their relation to boss and employee
then in Account have morphto relation call it specificAccount()
to which in its child morphs have the morph relation to Account
then add it to $with so to eager load them so when fetching account you could simply do
$account ->specificAccount
to get its morph child. which is nullable
This is totally dynamic such that if you have other classes in future you can just add and add the morph relationship. This may be applied to any reflection or runtime evaluated and loaded classes/code though it is not advisable to do this, as you can always edit code to create new functionality without affecting previous.

why model name in eloquent are not as same as table name?

When you create model in laravel for eloquent, the User model is treated like a users table. Why is that? Can we use an exact table name for the model?
I think more than anything it's convention. I don't see why you couldn't create a Users model for your users table, but a User is an instance of users, which is why it's done that way. You can always specify the table the model uses with:
protected $table = 'name_of_table';
which can be different than the model name. For example, a Data model can use the table userdata, as long as you specify that.
Hope that helps.

Conditional Relationship in laravel Eloquent

Let I have 3 table named user, admin, post
My post table structure is
-id
-poster_id
-poster_type //if value is 1 then poster_id will be releted with user table. if value is 2 then poster_id releted with admin table.
Now How writte belongsTo relationship with two table based on poster_type value
I want to do in Post model like this
public function Author(){
return $this->belongsTo('User', 'poster_id')->where('poster_type', '1') //poster_type is the field of post table.
}
First of all, you are talking about a Polymorphic relationship, supported by eloquent. You should take a look at the documentation.
http://laravel.com/docs/eloquent#polymorphic-relations
Second, you are mixing Eloquent relationships with special data recovery functions, and that's something you should avoid. I suggest you split the relationship itself from the data recovery function.
Also, if you want to go one step further, keep the relationship in the model, and split the data recovery functions into a repository object.

Resources