How to establish a dynamic model relationship in Laravel? - laravel

I need to establish a dynamic relationship but I can't.
The table design is as follows.
Page Table
id
title
1
Hello world
2
Contact
Category Table
id
title
1
Electronics
2
Sports
Blog Table
id
title
1
First blog
Links Type
id
name
1
Page
2
Category
3
Blog
Links Table
id
type_id
relation_id
slug
1
1
1
page/hello-world
2
1
2
page/contact
3
2
1
category/electronics
3
2
2
category/sports
3
3
1
blog/first-blog
CODE
Controller:
$links = Links::with('title')->get();
return response()->json($links);
// I need to get the "title" key.
Links Model:
public function title() {
switch($this->type_id) {
case '1':
return $this->hasOne(Page::class, 'id', 'relation_id');
break;
case '2':
return $this->hasOne(Category::class, 'id', 'relation_id');
break;
case '3':
return $this->hasOne(Blog::class, 'id', 'relation_id');
break;
}
}
This state does not work because the model has not yet been formed.
Error Output
Call to a member function addEagerConstraints() on null
How should I go about it?
Thanks.

What you are doing can be achieved by using polymorphic relationships.
pages
id - integer
name - string
categories
id - integer
title - string
blogs
id - integer
title - string
link_types
id - integer
name - string
links
id - integer
link_type_id - integer
linkable_id - integer
linkable_type - string
Page, Category and Blog model should define these relationships
public function link_types()
{
return $this->morphToMany(LinkType::class, 'linkable', 'links')->using(Link::class);
}
public function links()
{
return $this->morphMany(Link::class, 'linkable')
}
LinkType model should define these relationships
public function pages()
{
return $this->morphedByMany(Page::class, 'linkable', 'links')->using(Link::class);
}
public function categories()
{
return $this->morphedByMany(Category::class, 'linkable', 'links')->using(Link::class);
}
public function blogs()
{
return $this->morphedByMany(Blog::class, 'linkable', 'links')->using(Link::class);
}
Link model should define these relationships
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Relations\MorphPivot;
class Link extends MorphPivot
{
/**
* Get the parent linkable model (blog, category, page).
*/
public function linkable()
{
return $this->morphTo();
}
public function link_type()
{
return $this->belongsTo(LinkType::class, 'link_type_id');
}
}
Eloquent Relationships - One To Many Polymorphic Relations
Eloquent Relationships - Many To Many Polymorphic Relations
$link = Link::with('linkable')->first();
$link->linkable->title;

Related

Laravel 5.7 query with 3 tables

I'm pretty new to Laravel and i got stuck with building a more complex query:
I've 3 tables with their models:
Codes:
id
description
factor
public function purposes() {
return $this->hasMany('App\Purpose', 'code_purposes', 'code_id', 'purpose_id');
//I could be wrong here
}
Purpose:
id
name
description
Code_purposes:
code_id
purpose_id
public function codes() {
$this->belongsToMany('App\Code'); //I could be wrong here
}
public function purposes() {
$this->belongsToMany('App\Purpose'); //I could be wrong here
}
What I want is to fetch all the codes with the condition where the purposes name = 'some_name'
I thought this would be easy with the relationships, but I can't figure it out.
So how do I do this in Laravel?
In Code model:
public function purposes() {
return $this->belongsToMany('App\Purpose');
}
In Purpose model:
public function codes() {
return $this->belongsToMany('App\Code');
}
Now you can get data like:
$codes = Purpose::where('name', 'some_name')->first()->codes;
Relation table name must be code_purpose. And no need any model for this table.
Source: Laravel Many To Many Relationships

Laravel - How can i get client's orders grouped by their status

I have a situation which I can't fix, I have 3 tables / models with structure as below :
Client Model : Client->hasMany(Order::Class)
Order Model : Order->belongsTo(Client::Class) and Order->belongsTo(Status::Class)
Status Model : Status->hasMany(Order::class)
I want to be able to get each client's orders grouped by their statuses, e.g : 3 cancelled - 4 completed - 5 processing
I tried this but didn't work :(
Client Model {
public function {
return $this->orders()->selectRaw('status_id, count(id) as total')->groupBy('status_id);
// orders() = is the relation a client hasmany orders
}
}
can anyone help please thanks
Define this way your relationship in the Client model
public function orders()
{
return $this->hasMany(Order::class);
}
public function getOrdersCompletedAttribute()
{
return $this->orders->where('id_status', 5)->count();
}
public function getOrdersProcessingAttribute()
{
return $this->orders->where('id_status', 1)->count();
}
Supposing status 1 = 'processing' and 5 = 'completed'
You can access de attribute like this:
$client->orders_completed
To get 4

Defining relations on same table Laravel 5.3

I have a refferal system in my application.ie, One user can reffer other.
Users table
id name
1 A
2 B
3 C
Referrals table
id referrer_id referee_id
1 1 2
2 2 3
I want to show the referrals made by a user.
User Model
public function referrals()
{
return $this->hasMany('App\Models\Referral','referee_id','id');
}
Referral Model
public function referrer_user()
{
return $this->belongsTo('Modules\User\Models\User','referrer_id','id');
}
public function referee_user()
{
return $this->belongsTo('Modules\User\Models\User','referee_id','id');
}
Defining hasMany relationship in User model and belongsTo relationship in Referrals Model, I'am not getting the desired result.
#foreach($user->referrals as $key => $referral)
{{dd($referral->referee_user->name)}}
#endforeach
This returning me the name of user itself(referrer) not the referee
You are referring the ManyToMany relationship the wrong way.
Anyways, it'll be much easier and efficient the following way.
id name referred_by
1 abc null
2 def 1
3 gfd 2
User Model
/**
* Who did he bring onboard?
*/
public function referrals(){
return $this->hasMany('....User', 'referred_by');
}
//Who brought him onboard..
public function referree(){
return $this->belongsTo('...User', 'referred_by');
}
Just check out the appropriate syntax.

Laravel eloquent use id from one table to search junction table?

So I have 3 tables
-Business
- id
-Address
- id
-business_address
- business_id
- address_id
And now at the moment when I go into a view business page I pass business->id from business table as $id:
public function displayBusiness($id) {
$business = Business::find($id);
$address = Address::find($id);
Which works absolutely fine at this moment but what if address has a different id?
so:
-Business
- id = 1
-Address
- id = 2
-business_address
- business_id = 1
- address_id = 2
So how can I modify that so that when id in business table = 1 it goes into business_address and find matching address id and bring back records that match it
What you should have is a relationship. So in your Business model you'd add the following.
public function addresses() {
return $this->belongsToMany(Address::class, 'business_address', 'address_id', 'business_id');
}
Then in your Address model you'd have the following.
public function addresses() {
return $this->belongsToMany(Business::class, 'business_address', 'business_id', 'address_id');
}
With this, you can now do the following.
public function displayBusiness($id) {
$business = Business::with('addresses')->find($id);
}
Then you access addresses by doing $business->addresses.
This is all based on what you currently have, so I'm assuming that one Address can belong to several Business. If this should not be the case, you'll need to refactor your relationship and database, as the pivot table isn't needed.

How do I store values into a table along with join query in laravel?

I have three tables:->
-- Student(PK userid)
-- Teacher(PK teacherid, FK userid ref...)
-- Rating(PK rateid, FK userid ref....., FK teacherid ref....)
I want to insert into rating table by joining with other tables. How do I achieve that in Laravel 5.2? Please help me out guys!
This can be done in Larvel using Polymorphic relationships
To make it simpler, here's a sample db structure:
student
id - integer
user_id - integer
teacher
id - integer
user_id - integer
ratings
id - integer
value - integer
rateable_id - integer
rateable_type - string
The rateable_id corresponds to either the id on teacher or student
The rateable_type is a string of the class name of the model that is rateable. This is added automatically for you, as explained below.
Your models should look like this:
Rating.php
class Rating extends Model
{
public function rateable()
{
return $this->morphTo();
}
}
Teacher.php
class Teacher extends Model
{
public function rating()
{
return $this->morphOne(Rating::class, 'rateable');
}
}
Student.php
class Student extends Model
{
public function rating()
{
return $this->morphOne(Rating::class, 'rateable');
}
}
Now, here's a small example on how to use this.
$student = Student::find(1);
$rating = new Rating();
$rating->value = 10;
$student->rating()->save($rating);
First you find a student. Then you create a new rating and add a value.
When you do $student->rating()->save($rating); the rateable_id and rateable_type are filled in for you, with the correct value for your Student.php model through the relationship. Simple with Laravel.

Resources