I'm getting problems calling relationships in laravel, I have 4 tables: users, tickets, stores, statuses. and I have a #OneToMany relationship in Users to Tickets (1 user have many tickets). the other relationships are #OneToOne (1 ticket have 1 store and status).
Now, I have 6 tickets in my table and 4 users, I can print the relationship to the 4 first tickets, but when I want to call the ticket 5 or 6, the relationship dissapears.
The same thing with store and status, I can print the relationship while the id of the ticket is not greater than the number of items I have in my table.
these are my models:
User Model:
class User extends Authenticatable
{
use Notifiable, HasRoles;
protected $fillable = [
'id','name', 'email', 'password',
];
protected $hidden = [
'password', 'remember_token',
];
public function tickets()
{
return $this->hasMany(Ticket::class, 'usuario_id');
}
}
Ticket Model:
class Ticket extends Model
{
protected $fillable = [
'comentarios', 'falla', 'modelo', 'no_serie', 'monto',
'usuario_id', 'status_id', 'store_id'
];
public function user()
{
return $this->belongsTo(User::class, 'id');
}
public function store()
{
return $this->hasOne(Store::class, 'id');
}
public function status()
{
return $this->hasOne(Status::class, 'id');
}
}
Store Model:
class Store extends Model
{
protected $table = "stores";
protected $primaryKey = 'id';
public $timestamps = false;
protected $fillable = [
'sucursal', 'dirección'
];
public function ticket()
{
return $this->belongsTo(Ticket::class, 'store_id');
}
}
Status Model:
class Status extends Model
{
public $timestamps = false;
protected $fillable = [
'status'
];
public function ticket()
{
return $this->belongsTo(Ticket::class, 'status_id');
}
}
Controller:
$tickets = Ticket::all();
return view('Admin.index', compact('tickets'));
View
#foreach($tickets as $ticket)
<li>{{ $ticket->user }}</li>
#endforeach
result:
Result of the foreach
In the view, I'm calling all the tickets ($tickets), and for each ticket, I print the relationship (user function). But in the result, you can see that just print first 4 relationships, (the number of my users), if I add 1 user, the relationship in the 5th ticket appears.
The Same problem with the other tables (store and status).
Replace user() relationship in Ticket moedel to:
public function user()
{
return $this->belongsTo(User::class, 'usuario_id', 'id');
}
in Ticket model you must change function to
public function user()
{
return $this->belongsTo(User::class, 'usuario_id', 'id');
}
or just public function user()
{
return $this->belongsTo(User::class);
}
Related
I have 3 tables (workflow, user, workflow_user) and I would like to select the view column of the workflow_user table.
class Workflow extends Model
{
public function user()
{
return $this->belongsToMany(User::class,'workflow_user');
}
}
class User extends Model
{
public function works()
{
//return $this->belongsToMany(Role::class);
return $this->belongsToMany(Workflow1::class,'workflow_user');
}
}
workflow_user table
class WorkflowUser extends Model
{
protected $table = 'workflow_user';
protected $fillable = [
'workflow1_id','user_id','view'
];
protected $primaryKey = 'id';
public $timestamps = false;
}
To get the data from the workflow_user table I do this
$workflow = User::find($idconnect)->works()->orderBy('created_at','desc')->paginate(10);
When I make this request it does not give me the data of the workflow_user(workflow1_id,user_id,view) table.
If you have a model for the pivot table, you should have it extend the Pivot class and use it in the relationship's definition.
Also, you need to manually include the fields that are not the foreign ids in the query result.
class Workflow extends Model
{
public function user()
{
return $this->belongsToMany(User::class, 'workflow_user', 'workflow_id', 'user_id')
->using(WorkflowUser::class)
->withPivot(['id', 'view']);
}
}
class User extends Model
{
public function works()
{
return $this->belongsToMany(Workflow::class, 'workflow_user', 'user_id', 'workflow_id')
->using(WorkflowUser::class)
->withPivot(['id', 'view']);
}
}
workflow_user table
class WorkflowUser extends Pivot
{
protected $table = 'workflow_user';
protected $fillable = ['workflow_id', 'user_id', 'view'];
protected $primaryKey = 'id';
public $incrementing = true;
public $timestamps = false;
}
$workflow = User::findOrFail($idconnect)
->works()
->orderBy('created_at', 'desc')
->paginate(10);
I have four tables in a database named: Category, User, Role and then Post. In the Category table I have a column category_id which by this column i can have multiple child in category.
Every user belongsToMany roles and categories and each category belongsToMany posts, i must get all posts by role which logged into our application
As you can see in below screen shot manager 1 and manager 2 belongsToMany programings, dart, flutter and php.
you can suppose manager 1 user id is 1 and manager 2 is 2 and both of them are manager role
my question is how can i get all posts which logged user belongsToMany categories by role
logged user is manager 1 and i want to get all posts which saved into categories from parent which that's PROGRAMINGS
for example:
$categories = Category::whereNull('category_id')->whereHas('users.roles', function($q){
return $q->whereLabel('is-manager');
})->with(['posts' => function ($query) {
$query->with('language');
}])->get();
dd($categories->pluck('posts'));
NOTE:
with #Med.ZAIRI answer which posted on this thread every user in MANAGER 2 which is't synced into MANAGER 1, can see all of MANAGER 1 posts
In the Model Category add a relationship, like:
/**
* this will get the parent category
*/
public function parentCategory()
{
return $this->belongsTo( Category::class, 'category_id', 'id' );
}
Then, try to get Posts with their categories and their parent
Categories, and the users with their Roles, like:
$posts = Post::with( ['category.parentCategory', 'user.roles'])->get()
my used models in this senario:
class Category extends Model
{
use SoftDeletes;
protected $guarded = ['id'];
protected $hidden = ['id', 'category_id'];
public function parentCategory()
{
return $this->belongsTo( Category::class, 'category_id', 'id' );
}
public function categories()
{
return $this->hasMany(Category::class);
}
public function roles()
{
return $this->belongsToMany(Role::class);
}
public function posts()
{
return $this->belongsToMany(Post::class);
}
public function users()
{
return $this->belongsToMany(User::class);
}
public function childrenCategories()
{
return $this->hasMany(Category::class)->with('categories');
}
}
class Role extends Model
{
protected $guarded = ['id'];
public function users()
{
return $this->belongsToMany(User::class);
}
public function permission()
{
return $this->belongsToMany(Permission::class);
}
public function hasPermission($permission)
{
return !!$permission->intersect($this->roles->permission)->count();
}
}
class User extends Authenticatable
{
use Notifiable, SoftDeletes, UsersOnlineTrait;
protected $guarded = [
'id',
];
protected $hidden = [
'password', 'remember_token',
];
protected $casts = [
'email_verified_at' => 'datetime',
'avatar_path' => 'array',
'experiences' => 'array',
];
public function group()
{
return $this->belongsToMany(UserGroup::class, 'user_user_group');
}
public function child()
{
return $this->hasMany(User::class)->with('child');
}
public function parent()
{
return $this->belongsTo(User::class, 'user_id');
}
public function properties()
{
return $this->hasOne(UsersProperty::class);
}
public function roles()
{
return $this->belongsToMany(Role::class);
}
public function hasRole($role)
{
return $this->roles->contains('id', $role);
/*if (is_string($role)) {
} else {
return !!$role->intersect($this->roles)->count();
}*/
}
public function hasRoleByName($role)
{
if ($role == null) return false;
if (is_string($role)) {
return $this->roles->contains('name', $role) || $this->roles->contains('label', $role);
} else {
return !!$role->intersect($this->roles)->count();
}
}
public function categories()
{
return $this->belongsToMany(Category::class);
}
}
In the Model Category add a relationship, like:
/**
* this will get the parent category
*/
public function parentCategory()
{
return $this->belongsTo( Category::class, 'category_id', 'id' );
}
Then, try to get Posts with their categories and their parent Categories, and the users with their Roles, like:
$posts = Post::with( ['category.parentCategory', 'user.roles'])->get()
Trait with methods to get all available posts for the logged in user
based on the role
class User extends Model
{
use HasFactory, Notifiable, HasPosts;
}
<?php
namespace App\Concerns;
use App\Models\Category;
use Illuminate\Support\Str;
use Illuminate\Support\Collection;
trait HasPosts
{
/**
* Get all available posts for the currently logged in user
*
* #return void
*/
public function posts()
{
$method = 'postsFor' . Str::studly(str_replace('is-', '', $this->roles->first()->label));
return $this->{$method}()->collapse();
}
/**
* Get all posts associated with all categories including
* their subcategories for the logged in Portal Manager
*/
public function postsForPortalManager(): Collection
{
return Category::with([
'subcategories.posts.language',
'posts.language'
])
->get()
->pluck('posts');
}
/**
* Get all posts for the logged in Manager which belong to
* one of the categories associated with the Manager
*/
public function postsForManager(): Collection
{
return $this->categories()
->with('posts.language')
->get()
->pluck('posts')
->filter(function ($collection) {
return !!$collection->count();
});
}
/**
* Get only the posts which belong to the categories for the Editor
* and which are authored by the logged in Editor
*/
public function postsForEditor(): Collection
{
return $this->categories()
->with([
'posts' => function ($query) {
$query->where('user_id', $this->id)->with('language');
},
'posts.language'
])
->get()
->pluck('posts')
->filter(function ($collection) {
return !!$collection->count();
});
}
/**
* Get only the posts which belong to the categories for the Writer
* and which are authored by the logged in Writer
*/
public function postsForWriter(): Collection
{
return $this->categories()
->with([
'posts' => function ($query) {
$query->where('user_id', $this->id)->with('language');
},
'posts.language'
])
->get()
->pluck('posts')
->filter(function ($collection) {
return !!$collection->count();
});
}
}
Then for any authenticated user we can fetch available posts with
$user->posts()
It works with the seed data you have provided.
ella is not able to see the post on Flutter and scarlett is not able to see the post on laravel
Only assumption here is that have taken the first role of the authenticated user to lookup the method used.
Add this to your roles model:
public function categories()
{
return $this->hasMany(Category::class);
}
After that you can reach posts from the user, like:
$authorizedUser->roles()->with('categories.posts')->get();
You can flatten the result to access posts directly as well
If your relationships are all many-to-many as below:
roles >-< users >-< categories >-< posts
and are all defined properly in the models, e.g.
// Role.php
public function users()
{
return $this->belongsToMany(User::class);
}
// User.php
public function categories()
{
return $this->belongsToMany(Category::class);
}
// Category.php
public function posts()
{
return $this->belongsToMany(Post::class);
}
then I'm pretty sure you should be able to do
$role = Role::find(1);
// get all posts from all categories from all users with $role
$posts = $role->users()->categories()->posts;
I have a relationship that is almost 5 levels deep.
In my blades I use this all time without a problem. For example:
{{ $user->team->department->region->company->name ?? ''}}
How would I go about querying all users that belong to a company?
$users = User::where($user->team->department->region->company->id, '=', 1)->get(); ?????
Company Relationships:
class Company extends Model
{
public function region() {
return $this->hasMany('App\Region', 'company_id', 'id');
}
}
Region Relationships:
class Region extends Model
{
public function company() {
return $this->hasOne('App\Company', 'id', 'company_id');
}
public function department() {
return $this->hasMany('App\Department', 'region_id', 'id');
}
}
Department Relationships:
class Department extends Model
{
public function region() {
return $this->hasOne('App\Region', 'id', 'region_id');
}
public function team() {
return $this->hasMany('App\Team', 'department_id', 'id');
}
}
Team Relationships:
class Team extends Model
{
public function department() {
return $this->hasOne('App\Department', 'id', 'department_id');
}
public function user() {
return $this->hasMany('App\User', 'team_id', 'id');
}
}
User Relationships:
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function team() {
return $this->hasOne('App\Team', 'id', 'team_id');
}
}
I know there must be some easy way to query through nested relationships that Laravel provides a way for or a some facility for, but I have yet to find any decent examples from Googling around.
You can use this package for your need.
https://github.com/staudenmeir/eloquent-has-many-deep
read the instructions, depth of the relationship is not limited.
In my product table for example i have this data
Laravel
Lumen
JavaScript
Eloquent
every this data maybe have prerequisite of this table, for example for Lumen user must be know laravel and for Laravel and Lumen user must be know Eloquent, how can i specify this prerequisite relationship on model?
i want to set one or many of this data on form, for example, for creating Laravel on table i can do select Eloquent or for Eloquent i can select Laravel and Lumen as an one prerequisite.
my Products model:
class Products extends Model
{
use Sluggable;
protected $table = 'products';
protected $guarded = ['id'];
protected $casts = [
'images' => 'array'
];
public function productCategories()
{
return $this->belongsToMany(ProductCategories::class);
}
public function payments()
{
return $this->hasMany(Payment::class);
}
public function user()
{
return $this->belongsTo(User::class);
}
public function sluggable()
{
return [
'slug' => [
'source' => 'main_title'
]
];
}
public function comments()
{
return $this->morphMany(Comment::class, 'commentable');
}
}
I have 3 models : Group, User, and Profile
Group relates to User with many to many relationship,
User relates to Profile with one to one relationship,
and User also has many to many relationship with Role model
the question is how to get the faculty property of profiles from user in a group whose role are "mentee" ?
i tried this, but it doesn't worked:
$faculties = collect($this->mentee()->profile->faculty;
this is the Group.php and the mentee() method
class Group extends Model
{
public function users()
{
return $this->belongsToMany(User::class);
}
public function mentee()
{
return $this->users()->whereHas(
'roles', function($q){
$q->where('name', 'mentee');
})
->get();
}
here's the User.php
class User extends Authenticatable
{
protected $fillable = [
'username', 'email', 'password',
];
public function profile()
{
return $this->hasOne(Profile::class);
}
public function owns($related)
{
return $this->id == $related->user_id;
}
public function groups()
{
return $this->belongsToMany(Group::class);
}
public function roles()
{
return $this->belongsToMany(Role::class);
}
public function hasRole($role)
{
if (is_string($role)) {
return $this->roles->contains('name', $role);
}
return !! $this->intersect($this->roles)->count();
}
}
lastly, here's the Profile.php
class Profile extends Model
{
protected $fillable = [
'user_id', 'name', 'nim', 'faculty', 'major', 'batch','religion', 'gender', 'phone', 'line_id',
];
public function user()
{
return $this->belongsTo(User::class);
}
}
please let me know if i should give more details