I have problem to get name from role_user table for each post. I have ACL, so i have 3 tables - users, roles, role_user.
My code looks like this:
Post model
public function user()
{
return $this->belongsTo(user::class);
}
User model.
public function posts()
{
return $this->hasMany(post::class);
}
Role model.
public function users()
{
return $this->hasmany(user::class);
}
PostController,
return view ('admin.posts',[
'posts' => Post::All()
]);
In blade I echo fx user name by:
#foreach ($posts as $post)
<tr>
<th scope="row">{{$post->id}}</th>
<td>{{$post->category->name}}</td>
**<td>{{$post->user->name}}</td>**
</tr>
#endforeach
But the problem is that i want to echo name of role ( from role_user table) for user who wrote post which i am looping.
update
Ok, i solved issue, but probaly there is a better wat. anyone?
I added to models:
User model:
public function roles()
{
return $this->belongsToMany(Role::class);
}
And changed role model:
public function users()
{
return $this->belongsToMany(user::class);
}
Post controller:
class PostController extends Controller
{
public function index()
{
return view ('admin.posts',[
'posts' => Post::with('user')->get(),
'roleUsers' => User::with('roles')->get()
]);
}
and in blade i am doing
#foreach ($posts as $post)
<tr>
<th scope="row">{{$post->id}}</th>
<td>
<p>
#foreach ($roleUsers as $roleUser)
#foreach($roleUser->roles as $role)
<p>
{{ $role->pivot->user_id === $post->user->id ? "Role: $role->name" : "" }}
</p>
#endforeach
#endforeach
I guess there could be a better solution.
Use withPivot() method on the relation. Instead of fetching it from the pivot attribute, it will be on the model, if fetched through the many to many relation.
public function users()
{
return $this->belongsToMany(user::class)->withPivot();
}
Then i would change the front end logic to something in the style of, assuming that all post would have a user with the given role, else you will need to do an if check.
#foreach ($roleUsers as $roleUser)
{{ $roleUser->roles->where('id', $post->user->id)->first()->name }}
#endforeach
You question has a lot of code, but this is the way i perceive it and hopefully it can get you closer to better understanding of it.
Ok i fix my problem, thank you for your help. I found many post's similar to my so I will show solution.
Realtion's:
User belongTo post.
Roles belongsToMany Users.
Users belongsToMany Roles.
DB structure:
users id|User_name
roles id|name
role_user id|user_id|role_id
And what I tried to achieve is while looping through all Post's in blade to display name of role which belongs to that post and solution is very simple.
#foreach ($posts as $post)
{{$post->user->roles->first()->name}}
#endforeach
Related
I have two Table names are User and Role Table. I have set manyTomany relations between them using pivot table name Role_User in Laravel Eloquent.
Now, I want to show both table data in together a view using Eloquent Relationship.(e.g. I want to show in my view a user from users table contain which role in roles table )
Here, is my eloquent relations.
public function roles()
{
return $this->belongsToMany('App\Role');
}
public function users()
{
return $this->belongsToMany('App\User');
}
My, Eloquent Relationship Query.
$users=User::with('roles')->get();
return view('admin',compact('users'));
I'm try in my View.
#foreach($users as $user)
<tr>
<td>{{$user->name}}</td>
<td>{{$user->email}}</td>
<td>{{$user->roles->name}}</td>
<td></td>
</tr>
#endforeach
When you call $user->roles, you get a collection of the roles back. So if you want to display them all in a single string, all you have to do is implode the collection on that string:
<td>{{$user->roles->implode('name', ', ')}}</td>
Your $user->rules is instance of Collection of Role model. You can use one more foreach:
#foreach($users as $user)
//do something with user
#foreach($user->roles as $role)
{{$role->name}}
#endforeach
#endforeach
This will work in Laravel 5.0 and above
If we have two Model User and Mark. Then Inside the User Model make a function for relation with Mark. Example
public function marks()
{
return $this->hasMany('App\Models\Mark');
}
So, If you want to display the User name will all his marks. Then inside the controller perform following way.
public function getUserMarks(){
$result = User::select('email', 'name')->where('email', 'usermail#example.com')->with(['marks'])->get();
return view('welcome', compact('results'));
}
I have model named 'PropertyLead' as,
class PropertyLead extends Model
{
public function leadPropertyDetails()
{
return $this->belongsTo('App\Models\Property\Property', 'Property_id','id');
}
public function user()
{
return $this->belongsTo('App\Models\Access\User\User','user_id','id');
}
public function propertyRatings()
{
return $this
->hasMany('App\Models\Property\PropertyRating','Property_id','Property_id');
}
}
In my controller I am trying to get data as ,
$leads = PropertyLead::with('leadPropertyDetails','user','propertyRatings')
->get();
Here in $leads variable i am getting all the data that I want but In 'propertyRatings' I am getting user_id and other details. I also want to get the name user who rated that property using that user_id in propertyRatings object. I am really troubled in this query. Thanks in advance.
Use nested eager loading syntax to load nested relationships:
PropertyLead::with('propertyRatings', 'propertyRatings.user', 'leadPropertyDetails', 'user')->get();
Then you be able to display user name with:
#foreach ($leads as $lead)
#foreach ($lead->propertyRatings as $propertyRating)
{{ $propertyRatings->user->name }}
#endforeach
#endforeach
I have relations like this
User->hasMany->reviews
Review->belongsTo->user
Review->hasMany->ReviewAnswer
ReviewAnswer->belongsTo->Review
Now I try to display answers for specific review. My reviewAnswer table looks like:
Id, review ID, text
But the problem is when I do that:
#foreach($user->reviews as $data)
#foreach($data->reviewAnswers->where('review_id', $data->id) as $answer)
{{$answer->text}}
#endforeach
#endforeach
Then reviews displays okay, but I get the same answers for every review. How to repair that?
Make sure to check if all the relationships are correct. In this example, I assume that your models are stored in your app folder.
First, your User model should have reviews
public function reviews() {
return $this->hasMany("App\Review", "user_id", "id");
}
Next, set up your Review model to have answers
public function answers() {
return $this->hasMany("App\ReviewAnswer", "review_id", "id");
}
Then this is how you'll get all users with their respective reviews and answers
$users = User::with("reviews.answers")->get();
Finally, peform the loop in your view
#foreach($users as $user)
#foreach($user->reviews as $review)
#foreach($review->answers as $answer)
#endforeach
#endforeach
#endforeach
Try using the hasManyThrough() option which the eloquent models provide you.
Link: Laravel Eloquent Relations
This means in your case you would add:
class User extends Model {
public function reviewAnswers(
return $this->hasManyThrough(ReviewAnswer::class,Review::class);
)
}
and then simply access it in blade as:
#foreach($user->reviewAnswers() as $reviewAnswer) {
{{$reviewAnswer->text}}
}
I have User, Role and Permission model. User's have relation only with role and role to permission only, so Users and permissions have no connection between.
Role model
public function users(){
return $this->belongsToMany('App\User', 'role_user', 'user_id', 'role_id');
}
public function permissions(){
return $this->belongsToMany('App\Permission', 'permission_role', 'permission_id', 'role_id');
}
User model
public function roles(){
return $this->belongsToMany('App\Role', 'role_user', 'user_id', 'role_id');
}
Permission model
public function roles(){
return $this->belongsToMany('App\Role', 'permission_role', 'permission_id', 'role_id');
}
So I'm able to get the users role if I do
$users->roles
Now how can I get the users role permissions directly using my User model which connected only with roles and roles that only one who connects with permission
$users->role()->permission
If you are looking to just display the permissions on the user's profile, for example, a nested foreach will do the trick:
<p class="strong">Roles:</p>
<ul class="list-group">
#foreach ($user->roles as $role)
<li class="list-unstyled">{{ Html::link(url('/roles/'.$role->id),$role->label) }}</li>
<ul class="list-group">
#foreach ($role->permissions as $permission)
<li class="list-unstyled">{{ Html::link(url('/permissions/'.$permission->id),$permission->label) }}</li>
#endforeach
</ul>
#endforeach
</ul>
Laravel provides a hasManyThrough method which is exactly what you need. The "has-many-through" relationship provides a convenient shortcut for accessing distant relations via an intermediate relation. For example, a Country model might have many Post models through an intermediate User model. With the help of this method, you can easily gather all blog posts for a given country. You can learn more about this relationship in the official docs:
https://laravel.com/docs/5.5/eloquent-relationships
hasManyThrough will not work with many-to-many relationships. You can use nested whereHas() to get permissions for authenticated user:
Permission::whereHas('roles', function ($q) {
$q->whereHas('users', function ($q) {
$q->where('id', auth()->id());
})
})->get();
And in the comments, you've asked about an inversed solution. If you want to get all users for specified permission, do this:
User::whereHas('roles', function ($q) use($permissionName) {
$q->whereHas('permissions', function ($q) use($permissionName) {
$q->where('name', $permissionName);
})
})->get();
I want to know how can I check if the current user has any order or not? if have show the list and if not show the message?
currently I'm using this but it doesn't work well:
#if (empty(Auth::user()->order))
<blockquote>
<h1>Sorry you have no order at the moment, would you like to check out our products?</h1>
<footer>Click here</footer>
</blockquote>
#else
.......
#endif
user model:
public function order(){
return $this->hasMany(Order::class);
}
order model:
public function user(){
return $this->belongsTo(User::class);
}
my controller that shows orders history view:
public function index()
{
$user = Auth::user();
$orders = Order::where("user_id", "=", $user->id)->orderby('id', 'desc')->paginate(10);
return view('users.orders', compact('user', 'orders'));
}
You can count the orders using:
Auth::user()->orders->count()
To get this working there are a few prerequisite:
Have a correct DB schema
Have relations setup (it seems you need one-to-many
If you have this and assuming your relation is setup as:
class User extends Model{
/**
* Get the orders for the user
*/
public function orders(){
return $this->hasMany('App\Order');
}
}
You could use the forelse blade syntax
#forelse (Auth::user()->orders as $order)
<li>{{ $order->title }}</li>
#empty
<blockquote>
<h1>Sorry you have no order at the moment, would you like to check out our products?</h1>
<footer>Click here</footer>
</blockquote>
#endforelse
This will create a for loop in which you could declare the html layout for your order. If there are no orders the empty block will instead be used.