Laravel relationship between two tables with two foreign keys - php

Hey how can I make relationships between two table.
Users: id, email
Notification: id, user_id(id of the logged user), client_id(id of sender)
I would like make relationship between users and notifications by user_id and client_id.
Then I will can get all notifications assigned to logged user, and get email of sender users.
I made that:
public function notifications_with_client() {
return $this->hasManyThrough('App\Models\User', 'App\Models\Notification', 'user_id', 'id', 'client_id');
}
But when I using query i got good notifications but with wrong email.
I got email from ralationship id(from users table) == id(from notifications table)
My query
$column = 'notifications_with_client';
$value[1] = ['email', 'notifications.id', 'client_id'];
$query->with([$column => function($query) use ($value) {
$query->select($value[1]);
}]);
Someone know what I do wrong?

You can try it by defining the following relations:
User Model
public function notifications()
{
return $this->hasMany('App\Models\Notification');
}
Notification Model
public function to()
{
return $this->belongsTo('App\Models\User', 'user_id');
}
public function from()
{
return $this->belongsTo('App\Models\User', 'client_id');
}
And then you can query it as:
$notifications = auth()->user()->notifications()->with('from')->get();
Or if you just want email then query it as:
$notifications = auth()->user()
->notifications()
->with(['from' => function($q) {
$q->select('email');
}])
->get();

public function user()
{
return $this->belongsTo(Users::class, 'user_id');
}
public function client()
{
return $this->belongsTo(Users::class, 'client_id');
}
With this code in your Notification Model you can get the logged user with
$this->user(); // $notification->user();
and the sender with
$this->client(); //$notification->client();

You cannot use $this->hasManyThrough(). It use for a different reason
You can use $this->belongsTo() like this.
class User extends BaseModel
{
public function user()
{
return $this->belongsTo(Notification::class, 'user_id');
}
public function client()
{
return $this->belongsTo(Notification::class, 'client_id');
}
}
Then you can query like.
User::with(['user']);
or
User::with(['client']);

Related

Check user if is in chat room Laravel

I have models:
ChatRoomMembers
ChatRoom
so I want to check if auth user is in chat room
my relationships:
ChatRoom:
public function chatRoomMembers()
{
return $this->hasMany(ChatRoomMember::class);
}
ChatRoomMembers:
public function chatRoom()
{
return $this->belongsTo(ChatRoom::class);
}
public function user()
{
return $this->belongsTo(User::class);
}
So I created relationship in User Model:
public function chatRooms(){
return $this->hasManyThrough(
ChatRoom::class,
ChatRoomMember::class,
'user_id',
'id',
'id',
'chat_room_id'
)->orderBy('created_at', 'DESC');
}
and I am getting only this user chat rooms
In user model add below relationship
public function chatRoomMember(){
return $this->hasMany(ChatRoomMembers::class);
}
and in code
auth()->user()->chatRoomMember->count()
or
auth()->user()->chatRoomMember->exists()

Accessing a hasMany relation function via Collection

I am trying to get all of the users notifications, and depending on if the user is a buyer or seller (can be both). I have made two functions in my notifications table to filter each other out.
My goal is to ultimately run:
$notifications = Auth::user()->notifications()->getBuyerNotifications();
or
$notifications = Auth::user()->notifications()->getSellerNotifications();
I am running into an issue: Call to undefined method Illuminate\Database\Eloquent\Relations\HasMany
User Model:
public function notifications() {
return $this->hasMany('App\Notification', 'user_id', 'id');
}
Notifications Model:
public function user() {
return $this->belongsTo('App\User', 'id', 'user_id');
}
public static function getBuyerNotifications() {
return self::whereNotNull('buyer_id')
->whereNull('deleted_at')
->get();
}
public static function getSellerNotifications() {
return $this->whereNotNull('seller_id')
->whereNull('deleted_at')
->get();
}
The command I want to run to get all of the users notifications if they're a buyer: $notifications = Auth::user()->notifications()->getBuyerNotifications();
Firstly, you don't need to use whereNull('deleted_at'), you can import the softDeletes Trait in your model:
use Illuminate\Database\Eloquent\SoftDeletes;
...
class Notification extends Model {
use SoftDeletes;
...
}
Laravel will automatically use whereNull('deleted_at') on Eloquent-Builder.
Secondly, you cannot use static method on Illuminate\Database\Eloquent\Relations\HasMany.
Use scope method instead:
public function scopeBuyerNotifications($query) {
return $query->whereNotNull('buyer_id');
}
public function scopeSellerNotifications($query) {
return $query->whereNotNull('seller_id');
}
So you can find the notification like this:
$notifications = Auth::user()->notifications()->sellerNotifications()->get();
$notifications = Auth::user()->notifications()->buyerNotifications()->get();
Auth::user() uses session data.
Try this:
optional(User::find(Auth::id())->notifications)->getBuyerNotifications;
or
$userId = 1; // Example id you can just pass the user Id.
User::find($userId)->notifications->getBuyerNotifications;
You can add two other methods in user model as follows
public function getBuyerNotifications() {
return $this->hasMany('App\Notification', 'buyer_id', 'id');
}
public function getSellerNotifications() {
return $this->hasMany('App\Notification', 'seller_id', 'id');
}
And you can call it directly from the user instance
$user->getBuyerNotifications();
$user->getSellerNotifications();

Laravel eloquent insert data with multiple relationship

I have 3 tables:
User
- id
- email
UserAccount
- id
- user_id
- account_id
Account
- id
- user_id
Verification
- id
- user_id
- guid
I am trying to achieve a post whenever I try to add a user, it will automatically add an account with empty fields but with user_id in it, Verification table with user_id also, at the same time once the Account has been created it should also record UserAccount user_id and account_id but I ended up this error using many to many relationship belongsToMany and sync. How do I add the acct_id and user_id with eloquent?
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'acct_id' cannot be null (SQL: insert into `user_accounts` (`acct_id`, `user_id`) values (?, 17))
This is what I've tried so far.
Controller.php
$user = new User();
$user->name = "Not set";
$user->email = $email;
$user->password = NULL;
$user->save();
$accounts = new Account();
$accounts->email = $email;
$user->account()->save($accounts);
$userAccount = new UserAccount();
$userAccount->userAccount()->sync([
$user->id,
$accounts->id
]);
User.php
public function account()
{
return $this->hasMany(Account::class);
}
public function userAccount()
{
return $this->belongsToMany(User::class, UserAccount::class, 'user_id', 'id');
}
UserACcount.php
public function user()
{
return $this->hasMany(User::class, 'user_id', 'id');
}
public function account()
{
return $this->hasMany(Account::class, 'acct_id', 'id');
}
public function userAccount()
{
return $this->belongsToMany(Account::class, UserAccount::class, 'acct_id', 'user_id');
}
Verification.php
public function user()
{
return $this->belongsTo(User::class, 'user_id', 'id');
}
Account.php
public function user()
{
return $this->hasMany(User::class);
}
public function userAccount()
{
return $this->belongsTo(UserAccount::class);
}
I tried using this functionality and completely works fine but pretty sure this is how it works with eloquent.
$userAcct = new UserAccount();
$userAcct->create([
'user_id' => $user->id,
'acct_id' => $accounts->id
]);
Any thoughts?
I also have did found this related problem (Laravel hasManyThrough)
First of all, you should remove user_id from the account table because it is already referenced by user_account which links both tables. Moreover, if you wanna take advantages of Eloquent conventions which allow it to guess table names and fields, you should make sure your tables are named users, accounts, verifications and account_user.
User.php
public function accounts()
{
return $this->belongsToMany(Account::class);
}
Account.php
public function users()
{
return $this->belongsToMany(User::class);
}
The UserAccount model is useless if account_user exists only to links 2 tables.
Then, you may use an observer to get an event-based approach: whenever an user is created => do something
https://laravel.com/docs/5.8/eloquent#observers
<?php
namespace App\Observers;
use App\Account;
use App\Verification;
class UserObserver
{
/**
* Handle the User "created" event.
*
* #param \App\User $user
* #return void
*/
public function created(User $user)
{
(new Verification)->user()->associate($user);
$account = new Account;
$account->save();
$user->accounts()->attach([
$account->id
]);
}
}
// Post Model
public function user()
{
return $this->belongsTo('App\User');
}
public function categories()
{
return $this->belongsToMany('App\Category')->withTimestamps();
}
public function tags()
{
return $this->belongsToMany('App\Tag')->withTimestamps();
}
//User Model
public function posts()
{
return $this->hasMany('App\Post');
}
//Category Model
public function posts()
{
return $this->belongsToMany('App\Post')->withTimestamps();
}
//Tag Model
public function posts()
{
return $this->belongsToMany('App\Post')->withTimestamps();
}

Laravel defining relationship

Am still new to laravel
I have the following tables
user
id
first_name
last_name
educations
id,
user_id //references user id
type
Now in my user model i would like to get a specific users educations which can be many
so a user can have many educations but each education belongs to a single user.
So in my user model i have
public function education()
{
return $this->hasMany('App\ApplicantEducation','id','user_id');
}
In my Education model i have
public function user()
{
return $this->belongsTo('App\User','user_id','id');
}
But the above fails, I cannot retrieve user specific educations
Where am i going wrong?
try this:
in User Model:
public function educations()
{
return $this->hasMany('App\ApplicantEducation', 'user_id');
}
in Education Model:
public function user()
{
return $this->belongsTo('App\User', 'user_id');
}
Change return $this->hasMany('App\ApplicantEducation','id','user_id');
to return $this->hasMany('App\ApplicantEducation','user_id', 'id'); you also ommit the id and user_id.
As your foreign_key is well formed, you can also rwite this simple code,
class User{
public function education()
{
return $this->hasMany('App\ApplicantEducation');
}
}
Class Educations{
public function user()
{
return $this->belongsTo('App\User');
}
}
Here,
$this->hasMany('App\ApplicantEducation','id','user_id');
In above statement first argument should be Model second should be foreign key and the third one is any other key from Education model.
Here, second and third arguments are not mandatory.
In User Model
class User...{
public function education()
{
return $this->hasMany('App\ApplicantEducation');
}
In Education Model
public function user()
{
return $this->belongsTo('App\User');
}
Here, additional parameters are not mandatory might be your addition parameters creates issue,
and now you can retrieve your user with Education by
$user = User::with('education')->get();
This can retrieve all the users with their education.
I hope it helps,Thank you, Happy coding.
You should try this:
Education Model
public function user()
{
return $this->belongsTo('App\User','user_id);
}
User Model
public function education()
{
return $this->hasMany('App\ApplicantEducation');
}

Laravel 5.1 eloquent query syntax

I have the following model relationships. If a user logs in as an employee, I want them to be able to get a list of employees for a their company and the roles they have been assigned:
class User {
// A user can be of an employee user type
public function employee()
{
return $this->hasOne('App\Employee');
}
//
public function roles()
{
return $this->belongsToMany('App\Role');
}
}
class Employee {
// employee profile belong to a user
public function user()
{
return $this->belongsTo('App\User');
}
// employee belongs to a company
public function company()
{
return $this->belongsTo('App\Company');
}
}
class Company {
public function employees()
{
return $this->hasMany('App\Employee');
}
}
But the following query doesnt work. I get error Column not found: 1054 Unknown column companies.id in WHERE clause:
$employee = Auth::user()->employee;
$companyEmployees = Company::with(['employees.user.roles' => function ($query) use ($employee) {
$query->where('companies.id', '=', $employee->company_id)
->orderBy('users.created_at', 'desc');
}])->get();
The users and the employees table have a one to one relationship.
All employees have a base role type of employee in addition they may also have other roles such as manager, supervisor etc.
How do I write a query that gives me a company with all its employees and their roles?
I've tried to add a hasManyThrough relation to the Company model but that doesn't work either?
public function users()
{
return $this->hasManyThrough('App\User', 'App\Employee');
}
I think you're ring to get a list of coworkers for the current user and eager load the user and role?
$employee = Auth::user()->employee;
$companyEmployees = Company::with(['employees.user.roles')->find($employee->company_id);
Or perhaps:
$companyEmployees = Company::find($employee->company_id)->employees()->with('user.roles')->get();
$sorted = $companyEmployees->sortBy(function($employee){ return $employee->user->created_at; });
That might be a more direct route. Is your employee id in the user table or vice versa? The eloquent relationships are easy to set backwards.
Users::select('table_users.id')->with('roles')->join('table_employes', function($join) use ($employee) {
$join->on('table_employes.user_id','=','table_users.id')->where('table_employes.company_id', '=', $employee->company_id);
})->orderBy('tables_users.created_at')->get();
1. Create relationship for database table columns in migrtaion :
User Role
$table->foreign('user_id')->references('id')->on('users');
Users
$table->increments('id');
2. Create a model for each database table to define relationship
User.php (model)
public function userRoles()
{
return $this->hasOne('App\UserRoles', 'user_id', 'id');
}
Userroles.php (model)
public function user()
{
return $this->belongsTo('App\User', 'user_id', 'id');
}
3. Let controller handle database calls recommended to use REST api
Controller
use App\User;
use App\UserRoles;
class UserController extends Controller
{
public function index()
{
return User::with('userRoles')->orderBy('users.created_at', 'desc')->paginate(50);
}
}

Categories