Many to one on one table, relationship in laravel - laravel

I have model, named Magazine. This model represents of magazines table.
magazines
--id
--name
I also have model, named Transfer. This model is represents of transfers table.
In this table I would like store information about product transfers.
transfers
--id
--source
--target
There are two important columns, source is id of magazine from I getting product, target is id of magazine where I put the product.
How should I create relationship in Eloquent model? I did something like this
public function source()
{
return $this->belongsTo('Magazine', 'source');
}
public function target()
{
return $this->belongsTo('Magazine', 'target');
}
But, doesn't work. If I call $transfer->source I only get id, which is stored in this column(integer value). But I would like get Magazine object. If I change method name from source() to magazine(), Eloquent returns Magazine object, and this is correct.
How should I create relationship if source and target indicate on the same table

Your fields and methods overlap. So now you can do this:
$transfer->source()->getResult()->name;
but obviously this is not the way to handle relationships.
That said, to make it work as expected, rename either methods or table fields. I suggest this:
table transfers: id, source_id, target_id
// Transfer model
public function source()
{
return $this->belongsTo('Magazine', 'source_id');
}
public function target()
{
return $this->belongsTo('Magazine', 'target_id');
}

If you call $transfer->source you will only get the id.
You need to load your source too
$transfer = Transfer::with('source')->find(123);
and then access the name of the source
$nameOfSource = $transfer->source->name

Related

How can I make a relation from Table A to table C where A related to B and B is related to C in LARAVEL

How can I able display the info from "set Penalties" Table when I do something like: $loanApplication->duration->setPenalties->penalty?
LoanApplication Model:
public function loanDuration()
{
return $this->hasOne('App\LoanDuration', 'id','loan_duration_id');
}
LoanDuration Model:
public function loanApplications()
{
return $this->hasMany(LoanApplication::class);
}
You are almost there. $loadApplication->loadDuration should already give you information from the loan_durations table.
In your LoanDuration Model you should add a new relationship method like this:
public function setPenalties(): BelongsTo
{
return $this->belongsTo(<Your penalty model>);
}
This will allow you to retrieve the penalties from a LoadDuration:
$loadDuration->setPenalties;
Or with the full example, the result will be a collection of setPenalties:
$loanApplication->loadDuration->setPenalties
It could be possible that you wont get any results from the setPenalties. This is because of the name of the related column name in the database. You could either change the name of the column duration_id to loan_duration_id or specify the duration_id in the $this->belongsTo(<Your penalty model>, 'duration_id')

How to retrieve data through model?

I have Order model with another relation OrderPhoto:
public function OrderPhoto()
{
return $this->hasMany('App\OrderPhoto');
}
In turn OrderPhoto model has relation:
public function Photo()
{
return $this->belongsToMany('App\Photo');
}
So, how to get data from OrderModel with related data from third model Photo?
I guess this:
Order::with("OrderPhoto.Photo")->get();
to retrieve only data from Photo model for each Order
So, each Order has some OrderPhotos. Relationship is one to many.
But one item from OrderPhotos is related with primary key from table Photos. It is one to one relation.
My result query should be:
select `photos`.*, `ordersphoto`.`Orders_Id` from `photos` inner join `ordersphoto` on `ordersphoto`.`Photos_Id` = `photos`.`Id` where `ordersphoto`.`Orders_Id` in (1);
How to use hasManyThrough for this query?
Just having a quick look at your relationships it looks like you could create a hasManyThrough relationship on the order Model.
public function Photo {
return $this->hasManyThrough('App\OrderPhoto', 'App\Photo')
}
You may need to add the table keys to make it work
This will allow you to do:
Order::with("Photo")->get();
You can see more details here https://laravel.com/docs/5.5/eloquent-relationships#has-many-through
Update
Try this
public function Photo {
return $this->hasManyThrough('App\Photo', 'App\OrderPhoto', 'Order_id', 'Photos_id', 'id', 'id')
}
It is a little hard to get my head around your DB structure with this info but you should hopefully be able to work it out. This may also help
https://laravel.com/api/5.7/Illuminate/Database/Eloquent/Concerns/HasRelationships.html#method_hasManyThrough

Eloquent relationship for multiple table

I am working in laravel5.4. I have created four table as ticket, users, and company. Here, I have stored users id in ticket table. And stored company id in users table.
Here, I want to show ticket's user name with that users company name.
Here, I have create relation for it that looks like below.
Ticket model :
public function requesters(){
return $this->belongsTo('App\User','requester_id');
}
Here requester_id is who create ticket.
Users model :
public function company()
{
return $this->belongsTo('App\Models\Admin\Company');
}
Company model :
public function Users()
{
return $this->hasOne('App\Users');
}
Here, I have written query to get users information that looks like below.
Ticket::with('requesters')->orderBy('subject','asc')->paginate(10);
Now, I want to fetch company information or request_id So what changes should I have to do in this query to fetch company info along with ticket and users ?
If you want to to Eager load multiple relationship you can put them all in single with like this:
Ticket::with('requesters','requesters.company')->orderBy('subject','asc')->paginate(10);
but if you load nested relationship you can use shorter notation - you can omit parent relationship, so it's enough to use here:
Ticket::with('requesters.company')->orderBy('subject','asc')->paginate(10);
Try this, it should work for this case:
Ticket::with('requesters')
->with('requesters.company')
->orderBy('subject','asc')->paginate(10);

Use a different column on a many-to-many relationship in Laravel 4

I've got a situation in a project where I need to form a relationship between a primary key on one table and an indexed column (not the primary key) on another. Here's a sample of the database layout:
courses table
id
level
resources table
id
courses_resources table
course_level
resource_id
In my CourseResource model I have the following:
public function courses(){
return $this->belongsToMany('Course', 'courses_resources', 'resource_id', 'course_level');
}
Which works fine.
Then in my Course model I have:
public function resources(){
return $this->belongsToMany('CourseResource', 'course_resources', 'course_level', 'resource_id');
}
Which doesn't work. When I look at the last query performed on the database, it appears Laravel is searching the course_level column using the course's ID. That makes sense, but is there any way to use the level column for this relationship?
Eloquent BelongsToMany depends on PKs, so there is no way to do that with its methods.
You need custom relation object for this, that will check for given field, instead of primary key.
A quick and hacky solution would be this:
// Course model
public function getKey()
{
$relation = array_get(debug_backtrace(1, 2), '1.object', null);
if (method_exists($relation, 'getForeignKey')
&& $relation->getForeignKey() == 'courses_resources.course_level')
{
return $this->getAttribute('level');
}
return parent::getKey();
}
However if you would like to use it in production, do some extensive testing first.

Laravel 4: Return field from related table within Model function

I have a table 'sits' and it has user_id and sitter_id columns.
Inside of my User model, I have the following functions that all work perfectly and return almost everything I need.
public function mySits()
{
return $this->hasMany('Sit', 'sitter_id');
}
public function openSits()
{
return $this->hasMany('Sit')->where('sitter_id', '=', '0');
}
They work perfectly and returns almost everything I need. I say almost because what I need to do is reference the users table to get the name of the Sitter.
In the sits table, the sitter_id maps to id in the users table which has a name field.
Can I add something to the return data in the User model methods, or would I need do something in my controller.
$user = User::find(1)->load('mySits', 'openSits');
Just create a User relationship inside your Sit model. Then access it via $sit->user->name or similar.

Resources