Cant understand relationship eloquent in laravel - 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.

Related

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;

Accessing 3 tables in Laravel using foreign key (laravel 6)

I want to show data from a database(sql) that is from a specific user.
I have 3 tables:
Users
Stores
Areas
These are the following relationship between tables:
User hasOne Area
Area hasMany Stores
Basically what I wanted to show is that every user has their own area that has many stores.
User model
function area() {
return $this->hasOne('App\Area');
}
Area model
function user() {
return $this->belongsTo('App\User');
}
function stores() {
return $this->hasMany('App\Store');
}
Store Model
function area() {
return $this->belongsTo('App\Area');
}
My database looks like this:
user table
id name role_id area_id
area table
id name user_id
store table
id name area_id
How can I access user->area->store?
This is what I got so far
function show() {
$id= Auth::user()->id;
$user = User::find($id);
echo($user->area->stores);
}
Thank you
you can use the hasManyThrough for get sotres of an area:
define stores function in User model
public function stores()
{
return $this->hasManyThrough(Store::class, Area::class);
}
and use it :
$stores = auth()->user()->stores;
I hope be useful.

How to setup relationship between 2 table which has both one-to-many and many-to-many relationship?

I have a Users table and an Events table.
It's has one-to-many relationship.
Each user can create many event.
Each event belongs to one user.
Also, it has many-to-many relationship.
Each user can join as many event as they want.
Each event can be joined by many user.
This needs pivot table.
Now, I'm stuck.
This is event model.
public function user(){
return $this->belongsTo('App\User');
}
public function users(){
return $this->belongsToMany('App\User')
->withTimestamps();
}
This is user model.
public function events(){
return $this->hasMany('App\Event');
}
public function events(){
return $this->belongsToMany('App\Event');
}
The problem is in the user model where I can't define multiple function with the same name.
So, is there a way to do this correctly?
Quick answer
Of course you can't have two functions with the same name. In your case, try to use more specific names for each function:
public function createdEvents()
{
return $this->hasMany('App\Event');
}
public function joinedEvents()
{
return $this->belongsToMany('App\Event');
}
Recommendation
You can use a single many-to-many relationship to manage both relations with Pivot information:
users table
id
username
...
events table
id
name
...
event_user table
user_id
event_id
is_creator (default FALSE, unsigned integer)
...
Then when creating an event, relate the user and event objects and set the is_creator field to TRUE.
So in your User model:
app/User.php
public function events()
{
return $this->belongsToMany('App\Event')->withPivot('is_creator');
}
Then in your controller when you want to create an event:
app/Http/Controllers/SomeCoolController.php
public function store(CreateEventRequest $request)
{
// Get your event data
$data = $request->only(['your', 'event', 'fields']);
// create your object
$newEvent = Event::create($data);
// create the relationship with the additional pivot flag.
auth()->user()->events()->attach($newEvent, ['is_creator' => true]);
// the rest of your code.
}
And when a user want to 'join' an event:
app/Http/Controllers/SomeCoolController.php
public function join(JoinEventRequest $request)
{
// Get the event
$event = Event::find($request->event_id);
// relate the ev
auth()->user()->events()->attach($newEvent, ['is_creator' => false]);
// or just this, because its already set to false by default:
// auth()->user()->events()->attach($newEvent);
// the rest of your code.
}
It seems like it's many to many relationships between User and Event so there will be pivot name like user_event
user model
public function events() {
return $this->belongsToMany('App\Event')->using('App\UserEvent');
}
Reference: https://laravel.com/docs/5.7/eloquent-relationships#many-to-many

Laravel hasManyThrough getting through another model

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();

laravel 5 pivot table

I'm trying to implement a friendlist for a user
so a user can have many friends
but for calling the friends I'm having trouble getting my relation right:
user
id
friends
user_id
friend_user_id
Class user:
public function Friends(){
return $this->hasMany('App\User', 'friends');
}
So Auth::User()->Friends should return a list of User models
You actually don't have a "one to many" relationship but rather "many to many" with friends being your joining table
Try this:
public function Friends(){
return $this->belongsToMany('App\User', 'friends', 'user_id', 'friend_user_id');
}
When creating a relation to the same model, you would do something like this:
Models/User.cs
public function Friends()
{
return $this->hasMany('User', 'user_friend_of', 'id'); // assuming user_friend_of is the FK on user-table
}
public function User()
{
return $this->belongsTo('User');
}
This would mean you have only 1 table, which has a foreign key to another row in the same table, for instance: (id - name - user_friend_of )
In your user class, define the function as follows:
public function Friends(){
return $this->hasMany('friends');
}
Calling $user->Friends()->get() should return you everything you need. Note that 'friends' should be the name of the table.

Resources