Laravel hasManyThrough getting through another model - laravel

I have this 3 tables. I would like to get the employee name who created the client
I have tried this
class LeadsModel extends Eloquent
public function researcher_name()
{
$user = $this->belongsTo('users','id','user_id');
return $user->getResults()->belongsTo('employees','id','employee_id');
}
But it returns an error:
"message":"SQLSTATE[42S22]: Column not found: 1054 Unknown column 'employees.employee_id' in 'where clause' (SQL: select * from `employees` where `employees`.`employee_id` in (4))"}}
when I switch the id and employee_id, it does not return any relationship for users and employees.
Basically, I need to get the clients with the employee's name who created it.

Assuming relationships:
Client belongsTo User
User belongsTo Employee
simply call this:
$client->user->employee;
Given your schema, here are the relations you need in order to get an Employee related to particular Client (through User):
// Client model
public function user()
{
return $this->belongsTo('User');
}
// User model
public function employee()
{
return $this->belongsTo('Employee');
}
then simply call this:
$client = Client::find($someId);
$client->user; // single user related to the client
$client->user->employee; // single employee related to the user
You might want to check if given relation exists first:
// just an example, don't write it this way ;)
if ($client->user) { // user is not null
if ($client->user->employee) { // employee is not null as well
$client->user->employee->name; // name = field on the employees table
}
}

You need a Has Many Through relation.
Add the relationship in your Employee's model called clients:
public function clients()
{
return $this->hasManyThrough('App\Client', 'App\User');
}
And then you can use it like below:
Employee::first()->clients()->get();

Related

Wrapper for belongsTo returns null

2 tables - client and client_status
Table client:
id
client_status_id
name
This table contains 1 record with client_status_id and name filled.
Table client_status:
id
name
This table also not empty
Models for these tables:
class Client extends Model {
public function status() {
return $this->belongsTo(ClientStatus::class);
}
}
and
class ClientStatus extends Model {
protected $table = 'client_status';
public function clients() {
return $this->hasMany(Client::class);
}
}
When I assign $client somewhere in ClientController:
$client->name contains real client name
$client->status == null, so, I can't get $client->status->name (name of client status). Why and how to change?
The relationship is wrong, the user must have the status as has one, and the status belongs to user.
also from my opinion i would rather to save the user id, in the status table better. and it'll be much simple.

Check in relationship if a column is true, Laravel

I have 2 tables: roles & users.
In users I have role_id, and I want to check if that role has a column "access_admin_area" on true. If true, I am using a middleware.
Gate::define('admin', function ($user) {
return !empty($user->roles()->where('access_admin_area', true)->first());
});
From User model:
public function roles()
{
return $this->hasOne(Role::class);
}
SQLSTATE[42703]: Undefined column: 7 ERROR: column roles.user_id does not exist↵LINE 1: select * from "roles" where "roles"."user_id" = $1 and "role..
The error describes the issue pretty nicely here - the hasOne relationship method inside your User model expects the Role table row to have a user_id column that specifies a foreign key referencing the user table id column.
If I was you, I'd rather use hasMany relationhip between your User and Role model in this use case, since I expect your users and roles should have a many-to-many relationship
check out the many-to-many relationship eloquent and database structure in the laravel documentation https://laravel.com/docs/7.x/eloquent-relationships#many-to-many
Did you checked like this way:
public function roles()
{
return $this->hasOne('App\Role', 'id' , 'role_id');
}
You should change hasOne to belongsTo
then you can a simpler way to save yourselve from many where clauses in your controlleer is by creating another relationship with eg name as rolewithadminaccess
public function roles()
{
return $this->belongsTo(Role::class);
}
public function rolewithadminaccess()
{
return $this->roles()->where('access_admin_area', true)->limit(1);
}
then you can do this in your controller
return $user->rolewithadminaccess;

Laravel 5.8 Eloquent Model Relationship error

I have a relationship between two models, User and Follower.
User hasMany Follower, and Follower belongsTo User.
In my followers table in the database I have two columns, follower_id and following_id. Both these columns refer to the id column in the users table.
My follower and users table
followers
id
follower_id
following_id
users
id
name
username
User Model
public function followers(){
return $this->hasMany('App\Follower', 'follower_id');
}
public function followings(){
return $this->hasMany('App\Follower', 'following_id');
}
Follower Model
public function user(){
return $this->belongsTo('App\User');
}
In a test controller I am doing this:
$followed = Follower::find(2);
From here, I would like to select one of the columns, follower_id or following_id, and access the user that this particular row belongs to by using $followed->user->name. How would I go about that? Since I need to select a column before accessing, I am a little bit confused.
What can I do to access the data I need?
Your table should be :
followers
id
follower_id
following_id
user_id
users
id
name
username
In your Follower model :
public function user()
{
return $this->hasMany(Follower::class, 'user_id');
}
In your User model :
public function follower()
{
return $this->belongsTo(User::class, 'user_id');
}
Then you can query like this :
$follower = Follower::with('user')->findorFail(2);
$user_name = $follower->user->name;

Cant understand relationship eloquent in laravel

I want to select something like this from my users table:
select name from users where room.user1_id = user.id
My idea is to have two users in one room. In my User model i have these:
public function room(){
return $this->belongsTo('App\Room', 'user1_id');
}
In room model:
public function user(){
return $this->hasMany('App\User');
}
I tried to call like this in controller:
$room = Room::find($room_id);
return $room->user->name;
Here is an example:
https://www.youtube.com/watch?v=42l4nHl_aUM
at: 9:05
so this returns this error:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'users.room_id' in 'where clause' (SQL: select * fromuserswhereusers.room_id= 8 andusers.room_idis not null)
The relationship is backwards between rooms and users.
Change your User model to:
public function room(){
return $this->hasOne(App\Room::class, 'user1_id');
}
and Room model to:
public function user1 (){
return $this->belongsTo(App\User::class, 'user1_id');
}
public function user2 (){
return $this->belongsTo(App\User::class, 'user2_id');
}
However, if user(s) could be assigned rooms in the future for difference events, reservations, etc. it would be better to create a pivot table and use a many-to-many relationship. Convention would have it named room_user and defined in a migration as:
$table->unsignedInteger('room_id');
$table->unsignedInteger('user_id');
$table->foreign('room_id')->references('id')->on('rooms');
$table->foreign('user_id')->references('id')->on('users');
Then your model relationships would change to:
// User.php
public function rooms (){
return $this->belongsToMany(App\Room::class);
}
// Room.php
public function users (){
return $this->belongsToMany(App\User::class);
}
Any additional constraints could be later applied through a query scope or filtering of the resultant collection.

Laravel Eloquent Relation Model

I have 3 table on my database :
table 1 = user (hasMany order)
table 2 = order (hasMany order_detail, belongsTo user)
table 3 = order_detail (belongsTo order)
On my order_detail model i add this function :
public function order() {
return $this->belongsTo('App\Order');
}
so i can call the order data without define it from controller, i just define order_detail on my controller
$order_detail->order->invoice_number
but how to call the user data from the order detail?
I try use this
$order_detail->order->user
but it didn't work for me..
Is there any idea to call the grand parent relation?
In order model add function for order_detail:
public function order_details() {
return $this->hasMany('order_detail');
}
and for user:
public function user() {
return $this->belongsTo('user');
}
In user model add:
public function orders() {
return $this->hasMany('order');
}
Then, you can call in the controller:
$details = Order::find(1)->order_details->where('order_detail_id', 5)->first();
$userName = $details->username;
// ^
// column name in order_detail table
More info in the docs.
I think this is the more complete way to define the relationships:
// User model
public function orders(){
// I'm telling that users has many order. The orders have an user_id field that match with the ID field of the user.
return $this->hasMany('App/Order', 'user_id' , 'id');
}
// Order model
public function order_details(){
// I'm telling that order has many order_details. The order_details have an order_id field that match with the ID field of the order.
return $this->hasMany('App/OrderDetail', 'order_id' , 'id');
}
public function user(){
// I'm telling that an order belongs to an user. The user has an ID field that match with the order_id field of the order.
return $this->belongTo('App/User', 'id', 'user_id');
}
// OrderDetail Model
public function order(){
// I'm telling that an order detail belongs to an order. The order has an ID field that match with the order_id field of the order detail.
return $this->belongTo('App/Order', 'id', 'order_id');
}
I have seen that you put just the model name as first parameter in your relation definition. I think you must put the relative path from the root to the Model. In my case, I have the models as childs of the App folder.

Resources