I have 3 tables : projects - users - project_user.
This is a ManyOnMany relation so that's why I have a pivot table.
I got them linked via my model using belongsToMany.
Now comes my problem.
I have a table like this:
So I have a project selected, and a table with my users with active/contribute checkboxes.
When the active/contribute checkbox is checked the user will be linked to the project.
So in my head I have something like this:
When the checkbox is checked, it needs to send the user_id including the $this->project_idto the pivot table project_user so it will link the project <->user.
But now the problem is that I have no clue how I'm going to get this into working code.
HTML/Blade:
#foreach($users as $user)
<tr>
<td>
{{$user->firstname}} {{$user->middlename}} {{$user->lastname}}
</td>
<td>
<input name='contribute' type='hidden' value='0'>
{!! Form::checkbox('', '1', false) !!}
</td>
</tr>
#endforeach
Model:
User
public function projects()
{
return $this->belongsToMany('App\Project', 'project_user', 'user_id', 'project_id');
}
Project
public function users()
{
return $this->belongsToMany('App\User', 'project_user', 'project_id', 'user_id');
}
Controller:
public function edit($id, Project $project)
{
$users = User::all();
$project = $this->project->find($id);
return view('project.edit', ['project' => $project, 'id' => 'edit'], compact('users'));
}
public function update(CreateProjectRequest $request, $project)
{
$project = $this->project->find($project);
$project->fill($request->input())->save();
return redirect('project');
}
Tell me if any other code is needed to be provided
You can create Input arrays like below, but you have to check if this user is already associated with this project.
{!! Form::checkbox('contribute['.$user->id.']', '1', $checkifinproject) !!}
Then use sync when you are updating in your Controller.
But before that, because you want only the ids with value 1 from the checkboxes, you have to filter out the zero values, then keep only the keys of the array $request->input('users').
$project = $this->project->find($project);
$project->sync($prepared_ids);
Sync will then delete all the previous user_ids, associated with this project, from the table and save the new ones.
Related
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
I have this:
public function index()
{
$allusers = User::get(['id', 'first_name', 'last_name', 'postcode', 'preferred_role_id', 'email']);
return view('users.index', ['allusers' => $allusers]);
}
Now, preferred_role_id is an integer which points to an id in JobRoles model (job_roles) table, in where there is a field with a name of a job role. How do I pass that name to each of the users in $allusers? I would like to access it in the view like this:
#foreach ($allusers as $user)
<tr>
<td>
{{$user->first_name}}
</td>
<td>
{{$user->job_role}}
</td>
</tr>
#endforeach
You create a BelongsTo relationship from User to JobRole:
https://laravel.com/docs/5.6/eloquent-relationships#one-to-one
In you User model, you can add the relationship like this:
public function jobRole() {
return $this->belongsTo(App\JobRole::class, 'preferred_role_id');
}
Then change your view:
{{ $user->jobRole->name }}
To improve performance, you should use eager loading:
User::with('jobRole')->get(...);
I can't get the name property to display in my index always showing error
"Function name must be a string"
Controller
public function index()
{
$accounts = Account::with('student')->get();
return $accounts('Student_id');
$student = Student::find($id, ['id', 'studentname']);
return view('accounts.index',compact('accounts'));
}
Model
protected $fillable = [
'accountname',
'Student_id',
];
public function student() {
return $this->belongsTo(Student::class);
}
View Code:
<tbody>
#foreach ($accounts as $account)
<tr>
<td>{{ $account->accountname }}</td>
<td> {{$account->student->studentname}}</td>
</tr>
#endforeach
</tbody>
I'm trying to display the studentname instead of Student_id using one to many relationship.
this is the Error
Note: but if i changed this {{$account->student->studentname}} to this {{$account->Student_id}} it work but only showing the id not the name.
Remove these lines:
return $accounts('Student_id');
$student = Student::find($id, ['id', 'studentname']);
Also, since you're not using a standard foreign key name, you need to add it to the definition:
public function student()
{
return $this->belongsTo(Student::class, 'Student_id');
}
Also, it's a good idea to follow Laravel naming conventions which you will find in my repo and rename Student_id to student_id. In this case, your relationship will work without defining a foreign key.
Update
The solution for the third issue you have is:
<td> {{ optional($account->student)->studentname}}</td>
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've got 3 tables, the users table, the image table, and the favorites table which works sort of like a pivot table, as all it has is ID, image_id, and user_id.
In my user model, I have:
public function FavoritedByMe() {
return $this->hasMany('CommendMe\Models\Favorite', 'user_id');
}
In my favorites controller, I have:
public function getFavorites($username) {
$user = User::where('username', $username)->first();
return view('user.favorites')
->with('user', $user);
}
and this works just fine if I want to get the IDs of all the images I've favorited:
#foreach ($user->FavoritedByMe as $favorite)
{{ $favorite->image_id }}
#endforeach
However, what I'd really like to be able to return the view with the images themselves. Something like:
$favImages = Images::where('id', $user->FavoritedByMe->image_id);
return view('user.favorites')
->with('user', $user)
->with('favImages', $favImages);
Now obviously this won't work, and will return the error:
ErrorException in FavoritesController.php line 54: Undefined property: Illuminate\Database\Eloquent\Collection::$image_id
but perhaps some kind of Eloquent relationship would? I've tried making those work but they just don't "click" in my head.
How could I make this work?
Thanks in advance!
In your Favorite model add this relationship:
public function image()
{
return $this->belongsTo('YourImageModel');
}
Then you can acces the image like this:
#foreach ($user->FavoritedImages as $favorite)
{{ $favorite->image->yourProperty }}
#endforeach
In the laravel's best practices you should call your FavoritedByMe relationship favorites since it's obviously related to the user.