How to make this Eloquent relationship in Laravel - laravel

I have a table called users with a column username. Another table called students with a column code. I have made a hasMany relationship in User model like below and it's working fine.
public function students()
{
return $this->hasMany(Student::class,'code','username');
}
I have another table called institutes where a column is similar to students table named inst. I need to show data from institutes table while showing data of an user. How to make this relationship?
users table
username|mobile|address|password
students table
username|name|inst|roll|reg
institutes table
name|inst|address|phone
This is my home controller
public function index()
{
$admins = User::where('username','=',Auth::user()->username)->get();
return view('home', compact('admins'));
}
And this is my view
#foreach($admins as $key => $admin)
#foreach($admin->students as $student)
{{ $student->reg }}
#endforeach
#endforeach

Add migration to your Students table :
$table->unsignedBigInteger('user_id')->nullable();
$table->foreign('user_id')->references('id')->on('users')->onUpdate('cascade')->onDelete('set null');
Update your model User on students method :
return $this->hasMany(Student::class);
Add "with method"
$admins = User::where('username','=',Auth::user()->username)->with('students')->get();

Related

How to organize Laravel ORM for relationships table

I have two table Users and Relationships. The table Relationships contains next fields:
id | user_one_id (fk to users) | user_two_id (fk to users) | status | action_user_id
The status field can be one of 4 values. 0 - pending, 1 - accepted, 2 - rejected, 3 - blocked.
Action user is those user who created or updated request. For example, user with id 1 want to be a friend with user with id 2. action_user_id will 1.
I can't organize relationships in my User model.
For example my method friends
public function friends()
{
return $this->belongsToMany(User::class, 'relationships', 'id', 'user_one_id')
->orWhere('user_two_id', $this->id);
}
creates next sql query:
select * from "users" inner join "relationships" on "users"."id" = "relationships"."user_one_id" where "relationships"."user_one_id" = ? or "user_two_id" = ?
but I understand that it is not i need.
What i need? I need 3 methods "friends", "requested" and "blackList".
The "friends" method must return all friends of current user. The "requested" method must return all friend requests to current user. And the "blackList" must return all users who are in the blocked status of current user.
Try using a where clause, based on the status to retrieve the particular data. I recreated the problem in a fresh laravel install, and I used the user class and a relationships table to reffer to two users in a relationship
//Model User: $user->friends gets the list of friends of the user
public function friends()
{
return $this->belongsToMany('App\User', 'relationships','friend_2','friend_1')->where('friendship_status','friends');
}
At the blade.php view:
#foreach(\App\User::all() as $user)
<h5>{{$user->name}}</h5>
#foreach($user->friends as $friends)
<div>
<small>Is friends with {{$friends->name}}</small>
</div>
#endforeach
#endforeach
Relationships table migration:
Schema::create('relationships', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('friend_1');
$table->unsignedbigInteger('friend_2');
$table->string('friendship_status')->default('request pending');
$table->timestamps();
});
Manually added relationships:

Laravel how to define relationship based on two models or columns?

I have the following:
//users table
id
name
email
remeber_token
role_id
//roles table
id
name
//products table
id
name
//product_prices
role_id
product_id
price
The price of the product will vary depending on the user role, how to define the correct relationship so in blade I can do something like:
$product->price
and that will return the correct price depending on the user and the product?
I believe that when you say the user role, you refer to the role of the authenticated user.
The easiest approach is to define a HasOne relationship on the product model:
class Product
{
public function price()
{
return $this->hasOne(Price::class)->where('role_id', auth()->user()->role_id)
}
}
So from the view, you can simply say:
// Lets use optional() because there may not be any price for that product and user.
optional($product->price)->price
If there are many products involved, then using sub queries would make more sense.
class ProductsController extends Controller
{
public function index()
{
$products = Product::addSelect(['right_price' => Price::select('price')
->whereColumn('product_id', 'products.id')
->where('role_id', auth()->user()->role_id)
->limit(1)
])->get()
return view('products.index', compact('products'));
}
}
And then in the view:
#foreach($products as $product)
<p>{{$product->right_price}}</p>
#endforeach
For more info, pls check out this article.

Laravel Reference a One-to-Many Table through a Many-to-Many Relationship

I am having the most difficult time with this, and I'm not sure if the issue is the relationship or what. I have a 'users' table that has a many to many relationship (via a pivot table) with a 'practices' table. Practices, however, have a one-to-many relationship with a 'doctors' table, in which a practice can have many doctors, but a doctor can only belong to one practice. I also then have a many-to-many relationship between the doctors and a 'patients' table, which I would need to run counts and count-by-date sort of queries off of.
Currently, it is set to where a user can see what doctors they have by running a foreach loop on practices, and then on $practices->doctors. But this is not optimal, as the doctors then can't be sorted alphabetically and such. Can someone help me figure out how I can reference the doctor directly without needing the additional foreach loop?
This is my current code. Thanks in advance!
dashboard.blade.php
#foreach ($practices as $practice)
#foreach ($practice->doctors as $doctor)
Doctor Name: {{$doctor->full_name}}
Patient Count: {{$doctor->patients()->count()}}
#endforeach
#endforeach
DashboardController.php
$practices = User::find(Auth::user()->id)->practices();
return view('dashboard')->withPractices($practices);
there is no predefined eloquent relationship for your scenario. but we can create a relationship using another relationship.
I believe you have already created the relationship to 'practices' in the 'User Model' and 'doctors' in 'Practice Model'.
// in User Model
public function practices()
{
return $this->belongsToMany(Practices::class);
}
// in Practice Model
public funcion doctors()
{
return $this->hasMany(Doctor::class);
}
You need a 'doctors' relationship in the 'User Model'.
// in User Model
public function doctors()
$this->load(['practices.doctors' => function($query) use (&$relation) {
$relation = $query;
}]);
return $relation;
}
now you can get 'doctors' for a 'user' like this.
$doctors = User::find(Auth::user()->id)->doctors;
You can create a direct relationship by "skipping" the practices table:
class User extends Model {
public function doctors() {
return $this->belongsToMany(
Doctor::class,
'practice_user',
null,
'practice_id',
null,
'practice_id'
);
}
}

Laravel 5.5 Relationships - ErrorException Trying to get property of non-object

Can't display an info from DB to view, have an error
ErrorException
Trying to get property of non-object
Let me explain the logic:
User can create many companies
Companies can have many items
I don't have problems with inserting info to DB, everything is fine.
I can display every info from Users table and Company table in my Show View, but I can't display info from Company_Items tables in my view.
I guess something is wrong with my Relationships or keys, but what?
Trying to display Item name that belong to the specific company
{{$company->company_items->name}}
Company Table:
id(int)
company_name(string)
info(text)
user_id(int)
Company_items Table:
id(int)
company_id(int)
name(string)
Company Model:
class Company extends Model
{
protected $table = 'company';
//relation. MANY companies can be created by ONE user
public function user(){
return $this->belongsTo('App\User');
}
//relation. ONE company can have MANY items
public function item(){
return $this->hasMany('App\Item');
}
}
Item Model:
class Item extends Model
{
protected $table = 'company_items';
//relation. MANY items can be applied TO ONE company
public function company(){
return $this->belongsTo('App\Company');
}
}
Controller:
public function show($id)
{
$company = Company::find($id);
$user = User::find($id);
$company_items = Item::find($id);
return view('company_show')->with(['company' => $company,'company_items' => $company_items]);
}
View:
This is <b>{{$company->company_id}}</b> page info created by <b>{{$company->user->name}}</b><br>
Company category is <b>{{$company->company_category}}</b>.<br>
Item name is <b>{{$company->company_items->name}}</b>. // Can't display this expression
$company->company_items is a list of all the items of the company, you can't call a param on it. And you declared your relation with the name item and not company_items
Try to do :
$company->item[0]->name
or
#foreach($company->item as $item)
{{ $item->name }}
#endforeach
First error you made is:
$company_items = Item::find($id);
This will return the company Item that has the ID=$id which means it will return the Item that has the same ID as the company! I'm sure that's not what you want.
Instead you can do:
$company_items = $company->item;
which will return all the items of that company
and in your view you can access the items with a foreach loop:
#foreach($company_items as $item){
{{$item->name}}
}

Property [***] does not exist on this collection instance

I tried doing this for a website but my 'hotel' table has both an 'id' and a 'hotel_id' column. I heard eloquent recognizes the associated table name with _id as the primary key when defining a relationship. How would I define my relationship with the comments to the hotel? I have tried this in my Hotel model
public function comments() { return $this->hasMany(Comments::class, 'hotel_id') }
this is my controller for the page
public function hotelPage($hotel_id)
{
$hotels = Hotel::select(
'hotel.hotel_id'
,'hotel.name'
,'hotel.photo_url'
,'hotel.address'
,'hotel.desc_en'
//,'hotel.hotel_url'
,DB::raw("(CASE WHEN
COALESCE(hotel.hotel_url,'')!='' THEN
LOWER(CONCAT(hotel.hotel_url,'?aid=*******'))
ELSE
CONCAT(hotel.hotel_url,'http://www.example.com/?aid=*******')
END)
as hotel_url"))
->where('hotel.hotel_id',$hotel_id)
->get();
return view('hotel.hotelPage', ['hotels' => $hotels]);
}
and when I load the view
#foreach($hotels->comments as $comment) {{$comment->body}} #endforeach
I get the error "Property [comments] does not exist on this collection instance./ / /hotelPage.blade.php"
Please help, I am using laravel 5.4

Resources