How to override laravel model query? - laravel

I have a main model called User that returns all the users of the application.
There is a table called invites which manages the users invited to access the invitee panel. The invites table is thus linked to users:
So we have a general User model which handle all the users, and other two types of users:
Patient: user who invited the tenant
Tenant: user who has access to a list of associated patients
What I am trying to do is to fetch a patient list of a certain tenant (logged in user) using the eloquent relationship system, so I don't have to write a query for the join every time. Is it possible to do this?
At the moment, I tried this:
class Patient extends User
{
use HasFactory;
//protected $table = 'users';
public function getList()
{
return $this->belongsToMany(User::class, 'invites', 'id', 'user_id');
}
}
but of course this relationship not works because the query that should execute must be this:
SELECT u.*
FROM users u
INNER JOIN invites i ON i.user_id = u.id
WHERE i.tenant_id = 1
where id is the reference of the current user logged in which I retrieve using laratrust auth: auth()->user()->id.
Would be possible to return all the patients associated to the logged in user automatically? So simply calling:
Patient::query();
How can I achieve this?

To achieve that you should define relation and reverse many to many relation:
in your user model:
class Tenant extends User
{
use HasFactory;
protected $table = 'users';
public function patients()
{
return $this->belongsToMany(User::class, 'invites', 'tenant_id', 'user_id');
}
}
And in Patient model define reverse many to many relation by reverse belongToMany params :
class Patient extends User
{
use HasFactory;
protected $table = 'users';
public function tenants()
{
return $this->belongsToMany(User::class, 'invites', 'user_id', 'tenant_id');
}
}
To use the auth id for each model you have 2 option:
Option 1:
add column in users table that named user_type wich have type enum('tenant','patient') and depend user type use the appropriate model
Option 2:
by using custom auth guards , take look to this article
https://www.codecheef.org/article/laravel-8-login-with-custom-guard-example

Related

How to create relationship in Laravel 5 which will collect records of own model mentioned in pivot table?

I have 3 tables users, companies and pivot table with user_id, company_id.
I can't get users, which belongs to my company inside User model.
Tried like
belongsToMany('App\User','companies_users','company_id','user_id' );
but I get relation with wrong users.
Since you are having a belongsToMany relationship between the User and Company, the User belongs to more than one Company. To get users of the companies of a particular User will not be straight forward. If you are sure that is exactly what you want, then do this:
//inside the User model
public function companies()
{
return $this->belongsToMany('Company');
}
//inside the User model
public function companiesusers()
{
$users= new Illuminate\Database\Eloquent\Collection;
foreach($this->companies as $company)
{
$users = $users->merge($company->users->get());
}
return $users->unique();
}
//inside the Company model
public function users()
{
return $this->belongsToMany('User');
}
Then you can get a user's companiesusers like so:
User::first()->companiesusers();

Laravel Relationships: hasManyThrough, belongsTo, belongsToMany

Heyy, I have a Laravel project here, can u guys help me with this question about relationship?
I have the following database structure:
users
id
name
email
password
event
id
description
city_id
block_range
id
event_id
user_block_ranges
user_id
block_range_id
Explanation
users: A normal user authentication table. (has a belongsToMany relationship with user_block_ranges)
event: Stores event info. (has a hasMany relationship with block_range)
block_range: Save blocks of time of event. (has a belongsTo relationship with event)
The real question is: how do I get all the events of the user? Through the user_block_ranges then block_range relationship? Maybe using hasManyThrough?
Thanks in advance.
I believe your models look like this:
User model
class User extends Model
{
public function blockRanges()
{
return $this->belongsToMany('App\BlockRange', 'user_block_ranges', 'user_id', 'block_range_id');
}
}
Block Range model
class BlockRange extends Model
{
public function event()
{
return $this->belongsTo('App\Event');
}
}
To get all events of the user you can do this:
$user = App\User::find(1);
$events = array();
foreach ($user->blockRanges as $block_range) {
$events = $block_range->event;
}

Cannot access Collection::$items

I've got some troubles with an eloquent query.
Users have many feeds and feeds have many items.
I need to get all the items that belongs to the feeds of the user order by date.
I've got a pivot table:
feed_user
----------
- id
- feed_id
- user_id
and relationships are defined like this in my models:
class UsersController extends BaseController {
public function feeds() {
return $this->hasMany('feed');
}
class Feed extends \Eloquent {
protected $fillable = [];
public function users() {
return $this->belongsToMany('User');
}
public function items() {
return $this->hasMany('Item');
}
class Item extends \Eloquent {
protected $fillable = [];
public function feed() {
return $this->belongsTo('Feed');
}
But when I do this query...
Auth::user()->feeds->items->orderBy('date', 'DESC')->get();
It returns this error:
Cannot access protected property Illuminate\Database\Eloquent\Collection::$items
There are a couple issues here.
First, the relationship on User model is not correct. A hasMany relationship is one half a one-to-many relationship. This would assume that a feed belongs to one user, and that the feed table has the user_id field. A many-to-many relationship is defined by adding a belongsToMany relationship on both models. So, a user belongsToMany feeds, and a feed belongsToMany users.
class User extends \Eloquent {
public function feeds() {
return $this->belongsToMany('feed');
}
}
Next, the error you're seeing is because Auth::user()->feeds returns a Illuminate\Database\Eloquent\Collection object. You're then trying to access the items attribute on the Collection, which is protected and throws the error you're seeing.
Finally, since Laravel does not use joins for relationships, you cannot order a query by a field on a related table without manually doing the join yourself.
Try using eager loading:
Auth::user()->with('feeds.items')->orderBy('date', 'DESC')->get();

Laravel 4 - Display username based on ID

I have a posts and a users table.
In the posts table, i have a posts_author which is the ID of the user from the users table.
Is there an easy way to display the email address of the user, which is in the users table?
Cheers,
As long as you've set your relationships up it should just be a simple query.
http://laravel.com/docs/eloquent#relationships
Look at the one to many relationships.
(1 User, Multiple posts)
Remember to set the inverse of the relationship up also
If your model has the right relationships then should be as simple as $post->author->email().
You must tweak the author relationship because Eloquent assumes the key will be named author_id.
// Post
public function author() {
return $this->belongsTo('Author', 'posts_author');
}
// Author
public function posts() {
return $this->hasMany('Post');
}
Remember to use eager loading in case you are retrieving emails from more than one post object, or you will end up with n+1 queries.
Providing that you've configured the relationships properly, it should be pretty easy.
Post Model:
class Post extends Eloquent
{
protected $table = 'posts';
public function author()
{
return $this->belongsTo('User', 'posts_author');
}
}
Then User Model:
class User extends Eloquent
{
protected $table = 'users';
public function posts()
{
return $this->hasMany('Post', 'posts_author');
}
}
Then when loading the post you can do the following.
$post = Post::with('author')->find($id);
This will tell Eloquent to join on the users table and load the user data at the same time. Now you can just access all of the user information like this:
$post->author->username;
$post->author->email;
$post->author->id;
// etc etc
Obviously this is just a skeleton, but the assumption is that you have the rest setup.

How to perform a has many through statement using laravel eloquent?

Say i have three tables users,users_groups and groups.How can i get the user's groups through the users_groups table?
class User extends Eloquent {
protected $table = 'users';
}
class Groups extends Eloquent {
protected $table = 'groups';
}
class Usergroups extends Eloquent {
protected $table = 'users_groups';
}
As per your request, I've put together a simple example for your specific use case:
The Tables:
Eloquent suggests creating 3 database tables in such a scenario: users, groups and group_user.
The Laravel documentation states that:
The group_user table's name is derived from the aplhabetical order of the related model names.
The group_user table should contain the columns user_id and group_id which will contain the primary keys of group and user entries. The group_user table is what's known as a pivot table.
This conforms to 3NF (if you're interested).
The Models:
The User model should contain the following code:
<?php
class User extends Eloquent {
//...Other code…
public function groups()
{
return $this->belongsToMany('Group');
}
}
The Group model should contain the following code:
<?php
class Group extends Eloquent {
//...Other code…
public function users()
{
return $this->belongsToMany('User');
}
//...Other code…
}
You do not need a UserGroup model as found in your question.
Usage:
In order to retrieve all groups to which a particular user belongs you would do the following:
$user = User::find($user_id);
$user_groups = $user->groups();
Similarly in order to retrieve all users belonging to a particular group you would do the following:
$group = Group::find($group_id);
$group_users = $group->users();
In order to add/remove a user to a group would would do the following:
$user = User::find($user_id);
//Add a user
$user->groups()->attach($group_id);
//Detach a user
$user->groups()->detach($group_id);
Other:
You should read more in the Laravel docs about pivot tables here and about defining foreign keys (for your pivot table) in your migrations here.
I hope that helps!

Resources