How to ignore all related data in laravel - php

User.php
public function roles()
{
return $this->belongsToMany(Role::class)->withTimestamps();
}
public function hasRole($role)
{
if($this->roles()->where('name',$role)->first())
return true;
else
return false;
}
public function teams()
{
return $this->belongsToMany(Team::class)->withTimeStamps();
}
Team.php
public function users()
{
return $this->belongsToMany(User::class)->withTimeStamps();
}
Role.php
public function users()
{
return $this->belongsToMany(User::class)->withTimestamps();
}
Now i want to get all users that are not engaged with any teams and whose role is member

Take a look at this helper:
https://laravel.com/docs/5.8/eloquent-relationships#querying-relationship-absence
$users = User::doesntHave('teams')->get();
-- EDIT
$users = User::doesntHave('teams')->whereHas('roles', function($query) {
$query->where('name', 'member');
})->get();

Related

Eloquent Relationships Laravel connecting multiple tables together

i am attempting to rewrite all my joins into Elequent model relationships.
Here is what i have so far:
class SectionAndUser
{
public function sections()
{
return $this->belongsTo('App\Models\Section');
}
public function users()
{
return $this->belongsTo('App\Models\User');
}
...
class User
{
public function sectionAndUser()
{
return $this->hasMany('App\Models\SectionAndUser');
}
...
class Section
{
public function sectionAndUsers()
{
return $this->hasMany('App\Models\SectionAndUser');
}
...
With the select:
$sections = User::find($userId)->sectionAndUser()->get();
I get the result:
{
"id": 1,
"section_id": 1,
"user_id": 133
}
How do i now attach the 3 model section that carries all the data about section_id 1?
This is the join that i am hoping to achieve:
$id=Auth::id();
$results = DB::table('sections')
->join('section_and_users', function ($join) use ($id) {
$join->on('sections.id', '=', 'section_and_users.section_id')
->where('section_and_users.user_id','=', $id);
})
->get();
The expected result:
{
"id": 1,
"section_id": 1,
"section_name": 'sectionName'
"user_id": 133
}
I think the solution is to create only models Section and User, and add the relationship as BelongsToMany.
class User
{
public function sections()
{
return $this->BelongsToMany('App\Models\Section');
}
...
And
<?
class Section
{
public function users()
{
return $this->BelongsToMany('App\Models\User');
}
...
And of course, you need to create the pivot table. You can consult BelongsToMany documentation.
If you use this way, you can simple get the result with this query:
$section = Section::find(1); // This will return all your Section data
$section_related_users = $section->users; // This will return a collection of Users
You could do it this way
$id=Auth::id();
$results = SectionAndUser::where('user_id', $id)->with('users', 'sections')->get();
then you could map it to get your desired output
$sections = collect($results)->map(function ($section){
return [
'id' => $section->id,
'section_id' => $section->id,
'section_name' => $section->sections->name,
'user_id' => $section->user_id
];
});
You can create a many-to-many realtionship without the SectionAndUser-model.
With the belongsToMany-method, you can pass the name of the pivot table as a second argument. You can view Illuminate\Database\Eloquent\Concerns\HasRelationships#belongsToMany if you want to know what other arguments you can pass.
Section:
class Section extends Model
{
...
public function users()
{
return $this->belongsToMany(User::class, 'section_and_users');
}
...
}
User:
class User extends Model
{
...
public function sections()
{
return $this->belongsToMany(Section::class, 'section_and_users');
}
...
}
Then use it as this:
$user->sections->where(...
// 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();
}
// Role Model
public function users()
{
return $this->hasMany('App\User');
}
// User Model
public function role()
{
return $this->belongsTo('App\Role');
}
public function posts()
{
return $this->hasMany('App\Post');
}
//Tag Model
public function posts()
{
return $this->belongsToMany('App\Post')->withTimestamps();
}
// Catgory Model
public function posts()
{
return $this->belongsToMany('App\Post')->withTimestamps();
}
// controller
public function index()
{
$posts = Post::latest()->get();
return view('admin.post.index',compact('posts'));
}
// posts tabel to user result get
foreach($posts as $post){
$post->user->name
}

Call to a member function toArray() on integer

User.php
public function role()
{
return $this->belongsToMany('App\Models\Role','user_role','user_id','role_id');
}
//проверка принадлежит ли пользователь к какой либо роли
public function isEmloyee(){
$role=$this->role->toArray();
return !empty($role);
}
//проверка имеетли пользователь определению роли
public function hasRole($check){
return in_array($check,array_pluck($this->role->toArray(),'name'));
}
//получение идентификатора роли
private function getIdinArray($array,$term){
foreach ($array as $key => $value){
if ($value == $term){
return $key +1;
}
return false;
}
}
//добавление роли пользователя
public function makeEmployee($title){
$assiqned_role = array();
$role = array_pluck(Role::all()->toArray(),'name');
switch ($title){
case 'admin':
$assiqned_role[] = $this->getIdinArray($role,'admin');
case 'client':
$assiqned_role[] = $this->getIdinArray($role,'client');
break;
default:
$assiqned_roles[] = false;
}
$this->role()->attach($assiqned_role);
}
Role.php
class Role extends Model
{
public function users()
{
return $this->belongsToMany('App\Models\User','user_role','role_id');
}
}
OwnerMiddleware.php
<?php
namespace App\Http\Middleware;
use Closure;
class OwnerMiddleware
{
public function handle($request, Closure $next,$role)
{
if(!$request->user()->hasRole($role)) {
return redirect('/');
}
return $next($request);
}
}
You have role column in database. It preserves access to your role relation collection. You should delete it or rename role() relation for example to roles(). Moreover, belongsToMany implies that user can have many roles.
In addition, I want to note that the collection has its own methods in_array => contains, array_pluck => pluck. You could optimize your code like that:
public function roles()
{
return $this->belongsToMany(Role::class, 'user_role');
}
public function isEmloyee(){
return $this->roles->isNotEmpty();
}
public function hasRole($name){
return $this->roles->pluck('name')->contains($name);
}
public function makeEmployee($name){
$role = Role::where('name', $name)->first();
if($role){
$this->role()->attach($role->id);
}
}

How to use Multiple relationship in laravel 5.4

In my app i have define relationship (profile, user, level) but when I fetch data it is showing an error (Trying to get property 'email' of non-object) how can i solve this thank in advance.
this is User Model
public function profile()
{
return $this->hasOne(Profile::class, 'user_id');
}
Profile Model
public function user()
{
return $this->belongsTo(User::class, 'id');
}
public function level()
{
return $this->belongsTo(Level::class, 'id');
}
Level Model
public function profile()
{
return $this->hasOne(Profile::class, 'level_id');
}
This is Controller ProfileController
$users = Profile::with(['user', 'level'])->where('is_bd_partner', 'Yes')->get();
foreach ($users as $key => $value)
{
echo $value->first_name.'<br>';
echo $value->last_name.'<br>';
echo $value->user->email.'<br>';
echo $value->level->level.'<br>';
}
Note that belongsTo takes foreign_key as the first parameter.
So you should change the Profile Model as
public function user()
{
return $this->belongsTo(User::class, 'user_id');
}
public function level()
{
return $this->belongsTo(Level::class, 'level_id');
}
Read more here

How to associate a model with two or more other models in Laravel

I need to associate some models with at least two other models in an app that I'm developing, but I can't do the association in the controllers.
Here's the code.
UserModel
public function prices() {
return $this->hasMany(PriceClass::class);
}
PriceModel
public function user() {
return $this->belogsTo(ClassOfTheUser::class);
}
public function price_lines() {
return $this->hasMany(PriceLinesClass::class);
}
AreaModel
public function price_lines() {
return $this->hasMany(PriceLineClass::class);
}
PriceLinesModel
public function area() {
return $this->belongsTo(AreaClass::class);
}
public function price() {
return $this->belongsTo(PriceClass::class);
}
How may I do the creation of the Price, if I can't do something like:
public function store(Request $request) {
if ($request->ajax()) {
$user = UserClass::findOfFail($request->input("user_id"));
$user->prices()->save(new PriceClass());
$price = $user->prices()->lastest()->first();
foreach($request->input("price_lines") as $price_line) {
$area = AreaClass::findOrFail($price_line["area_id"]);
$area->price_lines()->save(new PriceLineClass());
$price_line_instance = $area->price_lines()->lastest()->first();
$price->price_lines()->save($price_line_instance);
}
}
}

Laravel "nested" with()

I have 3 models: Article, Comment, Reaction.
Each article has many comments, and each comment has many reactions:
App\Article:
class Article extends Model
{
public function comments() {
return $this->hasMany('App\Comment');
}
}
App\Comment:
class Comment extends Model
{
public function article() {
return $this->belongsTo('App\Article');
}
public function reactions() {
return $this->hasMany('App\Reactions');
}
}
App\Reaction:
class Reaction extends Model
{
public function comment() {
return $this->belongsTo('App\Comment');
}
}
In my ArticleController#index I want to fetch comments and their reactions:
ArticleController:
public function index()
{
$articles = Article::with('comments')
->select('articles.*')
->leftjoin('comments', 'comments.article_id', '=', 'articles.id')
->get();
return view('wiki')->withArticles($articles);
}
I can loop through the comments ($article->comments), however I'm not sure how to do a with('reactions') for the comments? i.e.,
#foreach($article->comments as $comment)
#foreach($comment->reactions)
// something like this...
#endforeach
#endforeach
you can do Nested Eager Loading
$article = Article::with('comments.reactions')
->leftjoin('comments', 'comments.article_id', '=', 'articles.id')
->select('articles.*')
->get();
You can also do this way
ArticleController:
public function index()
{
$articles = Article::with('comments')
->select('articles.*')
->get();
return view('wiki')->withArticles($articles);
}
App\Article:
class Article extends Model
{
public function comments() {
return $this->hasMany('App\Comment')->with('reactions');
}
}
App\Comment:
class Comment extends Model
{
public function article() {
return $this->belongsTo('App\Article');
}
public function reactions() {
return $this->hasMany('App\Reactions');
}
}

Categories