My code works. But I'm not sure is it a best solution. I need option to display user players and / or players from a group user belong to. Thank you for you time.
$user = $request->user();
$userGroups = $user->groups;
$friendsPlayers = [];
foreach ($userGroups as $group) {
$groupUsers = $group->users;
foreach ($groupUsers as $groupUser) {
if ($groupUser->id !== $user->id) {
$userPlayer = $groupUser->players;
foreach ($userPlayer as $player) {
if (!in_array($player, $friendsPlayers)) {
$friendsPlayers[] = $player;
}
}
}
}
}
1.Schema/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Schema::create('groups', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('info');
$table->timestamps();
});
Schema::create('players', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned()->index();
$table->string('name');
$table->string('url');
$table->string('type');
$table->integer('wins');
$table->integer('lost');
$table->integer('draws');
$table->timestamps();
});
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
Schema::create('group_user', function (Blueprint $table) {
$table->integer('group_id')->unsigned()->nullable();
$table->foreign('group_id')->references('id')
->on('groups')->onDelete('cascade');
$table->integer('user_id')->unsigned()->nullable();
$table->foreign('user_id')->references('id')
->on('users')->onDelete('cascade');
$table->timestamps();
});
2.Models/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class Group extends Model
{
protected $fillable = [
'name', 'info',
];
public function users() {
return $this->belongsToMany(User::class);
}
}
class Player extends Model
{
protected $guarded = [];
public function user() {
return $this->belongsTo(User::class);
}
public function leagues() {
return $this->belongsToMany(League::class)->withPivot('win', 'lost',
'draw')->withTimestamps();
}
class User extends Authenticatable
{
use Notifiable;
protected $fillable = [
'name', 'email', 'password',
];
protected $hidden = [
'password', 'remember_token',
];
public function players() {
return $this->hasMany(Player::class);
}
public function leagues() {
return $this->hasMany(League::class);
}
public function scoreboards() {
return $this->hasMany(Scoreboard::class);
}
public function groups() {
return $this->belongsToMany(Group::class);
}
}
This could be a perfect use case to use Laravel Collection.
$result = $user->load('groups.groupUsers.players')
->groups
->map->groupUsers
->collapse()
->filter(function ($groupUser) use ($user) {
return $groupUser->isNot($user);
})
->unique('id')
->map->players
->collapse()
->unique('id');
A different approach is using a query to get the result.
First, lets create a sub query to get all the groups the user joined.
$groupsJoinedByUser = Group::whereHas('users', function ($query) use ($user) {
$query->whereKey($user->id);
});
We can also create that sub-query this way:
$groupsJoinedByUser = Group::select('groups.*')
->join('group_user', 'groups.id', '=', 'group_user.group_id')
->where('group_user.user_id', $user->id);
Now we can create the query to get the players:
$players = Player::select('players.*')
->join('users', 'players.user_id', '=', 'users.id')
->join('group_user', 'users.id', '=', 'group_user.user_id')
->joinSub($groupsJoinsByUser, 'groups_joined_by_user', function($join) {
$join->on('group_user.group_id', '=', 'groups_joined_by_user.id')
})
->where('users.id', '!=', $user->id);
->distinct()
->get();
Related
I'm begginer in Laravel. I have this code:
class User extends Authenticatable implements MustVerifyEmail
{
use Notifiable;
use psCMS\Presenters\UserPresenter;
public static $roles = [];
public function roles()
{
return $this->belongsToMany('App\Role');
}
public function comments()
{
return $this->hasMany('App\Comments');
}
public function hasRole(array $roles)
{
foreach($roles as $role)
{
if(isset(self::$roles[$role]))
{
if(self::$roles[$role]) return true;
}
else
{
self::$roles[$role] = $this->roles()->where('name', $role)->exists();
if(self::$roles[$role]) return true;
}
}
return false;
}
}
class Role extends Model
{
protected $quarded = [];
public $timestamps = false;
public function users()
{
return $this->belongsToMany('App\User');
}
}
and schema:
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->bigInteger('company_id')->unsigned();
$table->foreign('company_id')->references('id')->on('companies')->onDelete('cascade');
$table->boolean('enable')->default(0);
$table->string('name', 120)->nullable();
$table->string('surname', 120)->nullable();
$table->string('email', 120)->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->bigInteger('counter')->default(0);
$table->rememberToken();
$table->timestamps();
$table->engine = "InnoDB";
});
Schema::create('roles', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->engine = "InnoDB";
});
Schema::create('role_user', function (Blueprint $table) {
$table->bigInteger('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->bigInteger('role_id')->unsigned();
$table->foreign('role_id')->references('id')->on('roles')->onDelete('cascade');
$table->engine = "InnoDB";
});
And my user:
DB::table('users')->insert([
'name' => 'Marian',
'surname' => 'La',
'email' => 'marian#icloud.com',
'email_verified_at' => \Carbon\Carbon::now(),
'password' => Hash::make('passw'),
]);
DB::table('role_user')->insert([
'user_id' => 1,
'role_id' => 1,
]);
This code work fine. I have problem with my role.
How can i print user role in blade?
I make this code:
public function getAdmin(int $id)
{
return User::find($id);
}
$admin = $this->getAdmin(1);
And now my $admin - has admin object.
When i print in blade file: $admin->name, $admin->surname - it's work.
When i print: {{ $admin->roles }}
i have result:
[{"id":1,"name":"admin","pivot":{"user_id":1,"role_id":1}}]
How can I show correct value (admin):
I need result: admin not this:
[{"id":1,"name":"admin","pivot":{"user_id":1,"role_id":1}}]
That is Many to Many relationship and each user may have many roles ! So use foreach to print all of rules in your blade :
#foreach ($admin->roles as $role)
{{ $role -> name }},
#endforeach
https://laravel.com/docs/5.8/eloquent-relationships#many-to-many
Hope this helps !
I have three table below:
I want to display all Related job post by category in Single jobpost. and I already have single job post page but in the same single job page I want to display related jobs in the left side. see my picture!
what is controller should be and in the Single job page (view) should be? please help?
My jobController
public function show($id, $company_id)
{
$singleJob = Job::find($id);
$company = Company::find($company_id);
$similarJob = Job::with('company')->where('category_id', $id)->get();
return view('pages.single-job')->with([
'singleJob'=> $singleJob,
'company'=> $company,
'similarJob' => $similarJob,
]);
}
My relationship
job.php
public function company(){
return $this->belongsTo(Company::class);
}
Job.php
public function category(){
return $this->belongsTo(Category::class);
}
//category.php
public function job(){
return $this->hasMany(Job::class);
}
//company.php
public function job(){
return $this->hasMany(Job::class);
}
Job table
Schema::create('jobs', function (Blueprint $table) {
$table->increments('id');
$table->integer('company_id');
$table->string('jobTitle');
$table->longText('jobDescription');
Company Table
Schema::create('company_types', function (Blueprint $table) {
$table->increments('id');
$table->integer('admin_id');
$table->string('name');
$table->timestamps();
});
Category table
Schema::create('categories', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id');
$table->string('name');
$table->timestamps();
});
You can use whereHas like this :
public function show($id, $company_id)
{
$singleJob = Job::find($id);
$company = Company::find($company_id);
$similarJobs = Job::with('company')
->whereHas('category', function ($query) use($singleJob) {
$query->where('id', $singleJob->category->id);
})
->get();
return view('pages.single-job')->with([
'singleJob'=> $singleJob,
'company'=> $company,
'similarJobs' => $similarJobs,
]);
}
And in the view you can use it like this :
#foreach ($similarJobs as $similarJob)
// Add the job partial, componnent or just your HTML here for showing the Job
#endforeach
For the question in the comment, to find jobs that have a company that belongs to a given industry :
$some_industry_type_id = 1;
$jobsOfIndustryType = Job::whereHas('company', function ($query) use($some_industry_type_id) {
$query->where('industry_type_id', $some_industry_type_id);
})
->get();
I'm trying to display the name of the assignee (foreign key from Users table) of each ticket by storing each name in an array from two UNION'd tables (Accesses and Reports) but it gives me this error. ErrorException
Undefined property: stdClass::$assignee.
//HomeController
$accesses = DB::table('accesses')
->select(array('id', 'fullname','emp_id','shift','state','resolved_at', 'closed_at','assigned_to'))
->where('state','=','Assigned');
$all = DB::table('reports')
->select(array('id', 'fullname','emp_id','shift','state','resolved_at', 'closed_at','assigned_to'))
->union($accesses)
->where('state', '=', 'Assigned')
->get();
$names[] = array();
foreach ($all as $one)//store in array to display in a chart
{
$names[] = $one->assignee->name; //error here
}
//Report Model
public function assignee()
{
return $this->belongsTo(User::class, 'assigned_to');
}
//Access Model
public function assignee()
{
return $this->belongsTo(User::class, 'assigned_to');
}
//Report Migration
public function up()
{
Schema::create('reports', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->nullable();
$table->string('fullname');
$table->string('emp_id');
$table->string('shift');
$table->longText('report');
$table->string('status')->default('Pending'); //Pending, Approved
$table->string('state')->default('Open'); //Open, Assigned, Resolved, Closed
$table->date('resolved_at')->nullable();
$table->date('closed_at')->nullable();
$table->integer('assigned_to')->nullable();
$table->longText('action')->nullable();
$table->timestamps();
});
}
//Access Migration
public function up()
{
Schema::create('accesses', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->nullable();
$table->string('fullname');
$table->string('emp_id');
$table->string('shift');
$table->string('request');
$table->longText('note')->nullable();
$table->string('status')->default('Pending'); //Pending, Approved
$table->string('state')->default('Open'); //Open, Assigned, Resolved, Closed
$table->date('resolved_at')->nullable();
$table->date('closed_at')->nullable();
$table->integer('assigned_to')->nullable();
$table->longText('action')->nullable();
$table->timestamps();
});
}
It gives me this error
The results should be like this
You should use merge method of collection:
$accesses = Access::select(array('id', 'fullname','emp_id','shift','state','resolved_at', 'closed_at','assigned_to'))
->where('state','=','Assigned')
->get();
$reports = Report::select(array('id', 'fullname','emp_id','shift','state','resolved_at', 'closed_at','assigned_to'))
->where('state', '=', 'Assigned')
->get();
$all = $accesses->merge($reports);
I have a 'favourite' functionality for my loops table. I am trying to achieve this with a pivot table. But now I'm trying to find the most efficient way to call all the logged in users favourited loops with eloquent.
loops table :
Schema::create('loops', function(Blueprint $table) {
$table->increments('id');
$table->string('name', 35);
$table->string('loop_path', 255);
$table->string('FK_user_id');
});
users table:
Schema::create('users', function(Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('password', 60);
});
favourites table :
Schema::create('favourites', function(Blueprint $table) {
$table->increments('id');
$table->integer('FK_user_id')->unsigned();
$table->integer('FK_loop_id')->unsigned();
});
Loop.php :
class Loop extends Model {
protected $table = 'loops';
public $timestamps = true;
public function user()
{
return $this->belongsTo('App\User','FK_user_id','id');
}
public function favourites()
{
return $this->belongsToMany('App\User', 'favourites', 'FK_loop_id', 'FK_user_id');
}
}
This is how I achieve this now , but it doesn't seem efficient :
$loops = Loop::with('favourites')->
with('user')->get();
$favouritedLoops = array();
foreach($loops as $loop)
{
//check if logged in user has favourited this
$user_favorites = Favourite::where('FK_user_id', '=', Auth::user()->id)
->where('FK_loop_id', '=', $loop->id)
->first();
if ($user_favorites != null)
{
array_push($favouritedLoops, $loop);
}
}
return Response::json($favouritedLoops);
You should define favouritedLoops method in User model, then You can easily access all favourited loops.
User.php
public function favouritedLoops()
{
return $this->belongsToMany('App\Loop', 'favourites', 'FK_user_id', 'FK_loop_id');
}
and return now will look like:
return Response::json(Auth::user()->favouritedLoops);
I have these 3 tables:
Schema::create('companies', function (Blueprint $table) {
$table->increments('id');
$table->integer('city_id')->unsigned();
$table->string('name');
$table->string('address');
$table->float('lat', 10,6);
$table->float('lng', 10,6);
$table->timestamps();
$table->foreign('city_id')->references('id')->on('cities');
});
Schema::create('company_clients', function (Blueprint $table) {
$table->increments('id');
$table->integer('company_id')->unsigned();
$table->integer('client_id')->unsigned();
$table->foreign('company_id')->references('id')->on('companies');
$table->foreign('client_id')->references('id')->on('companies');
});
Schema::create('cities', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
});
Now, I want to have an eloquent query, where it will return an array (Not only one item) of companies, where the (for example)company_id=1 on company_clients table. Also, the city_id is suppose to return the name and not the id, using the cities table. I cannot imagine how to do it right now.
I made:
class City extends Model
{
protected $table = 'cities';
public $timestamps = false;
protected $fillable = [
'name',
];
public function companies()
{
return $this->hasMany('App\Company', 'city_id', 'id');
}
}
class CompanyClients extends Model
{
protected $table = 'company_clients';
public $timestamps = false;
protected $fillable = [
'company_id', 'client_id',
];
public function companies()
{
return $this->belongsTo('App\Company', 'company_id', 'id');
}
public function clients()
{
return $this->belongsTo('App\Company', 'company_id', 'id');
}
}
class Company extends Model
{
protected $table = 'companies';
protected $fillable = [
'name', 'address', 'lat', 'lng', 'city_id',
];
protected $hidden = [
'clients', 'created_at', 'updated_at',
];
public function city()
{
return $this->belongsTo('App\City', 'city_id', 'id');
}
public function companies()
{
return $this->hasMany('App\CompanyClients', 'company_id', 'id');
}
public function clients()
{
return $this->hasMany('App\CompanyClients', 'client_id', 'id');
}
}
But, I'm missing the code in the controller. I tried:
$result = Company::leftJoin('company_clients', function($join) {
$join->on('companies.id', '=', 'company_clients.company_id');
})->where('company_clients.company_id', '=', 1 )->get();
or
$result = Company::with(['clients' => function($q){
$q->where('company_id', 1);
}])->get();
but is not returning the correct result. What I'm missing?
Thanks!
EDITED:
I had found a way, but I'm not sure if is the best way to do it. Can someone please confirm?
$result = Company::join('company_clients', function($join) {
$user = Auth::guard('api')->user();
$join->on('companies.id', '=', 'company_clients.client_id')->where('company_clients.company_id', '=', $user->company_id );
})->join('cities', 'cities.id', '=', 'companies.city_id')->get(array('companies.*', 'cities.name'));
Try
CompanyClients::with('company.city', 'clients')->where('company_id', 1)->get();
Rename
companies
relationship on the CompanyClients model to
company