I have made an edit page for my users and everything works except changing the role. I have made a select menu which displays all the roles through a foreach loop. And it displays the current role of the user like this:
<div class="form-group row">
<div class="col-md-4">
<label for="Datum">Rol:</label>
</div>
<div class="col-md-8">
<select class="form-control" id="Datum" name="role">
<option selected>{{ $user->role->role_name }}</option>
#foreach($roles as $role)
<option>{{ $role->role_name }}</option>
#endforeach
</select>
</div>
</div>
I want to be able to change the role by the role_name instead of ID. I honestly don't know where to look. How can I achieve this?
The controller that the form goes through looks like this:
public function updateUser(Request $request, $id)
{
$user = User::find($id);
$user->update($request->all());
$user->save();
return back()->with('flash', 'Account is geupdate');
}
In the database, a user has a role_id and in the role table, it has all the roles. So the relations are: User has a Role, Role has many users. These relations are set in the models. So {{ $user->role->role_name }} works just fine.
Thanks in advance!
Assume role_name is unique. In your post method you can do the following-
public function updateUser(Request $request, $id)
{
$role = Role::where('role_name','=',$request->input('role_name'))->first();
$user = User::find($id);
$user->role_id = $role->id;
$user->save();
return back()->with('flash', 'Account is geupdate');
}
As per your comment, add this on your user model-
public function setPasswordAttribute($password)
{
$this->attributes['password'] = bcrypt($password);
}
Hope it helps :)
Related
I have three user roles: Student, Teacher, Admin.
If a user is a student I want to display the option to Elevate them to either Teacher or Admin in a dropdown and the same for the other roles eg. Teacher gets Admin and Student option.
Currently this looks like this:
Index
#if ($user->role == 'admin')
<form action="/admin/users/{{ $user->id }}" method="POST">
#csrf
#method('PATCH')
<input class="hidden" name="role" value="user">
<button>Make User</button>
</form>
#else
<form action="/admin/users/{{ $user->id }}" method="POST">
#csrf
#method('PATCH')
<input class="hidden" name="role"value="teacher">
<button>Make Teacher</button>
</form>
#endif
Controller
public function update(User $user)
{
$attributes = request()->validate([
'role' => ['required', Rule::exists('users', 'role')]
]);
$user->update($attributes);
return back()->with('success', 'User Updated!');
}
How would I be able to do an if statement to list all the roles except for the current role assigned to the user or perhaps this is better done in the controller instead?
And is it possible to put the role in a slug and then run a foreach so I don't repeat code?
Im new top Laravel so any help would be appreciated :)
Thanks
Provide all roles to your page.
Add to User hasRole() method if it does not exists.
Use FormRequest for validation.
Don't forget to get roles with a $user to avoid n+1 queries with User::with('roles')->find($id).
#foreach($allRoles as $role)
#if(! $user->hasRole($role))
Your form
#endif
#endforeach
I've searched but couldn't find a working solution. I simply cannot update a specific field (status) in users table. I've added two additional fields in Laravel's auth users original table.
Here is the migration code:
public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->unsignedBigInteger('role_id');
$table->integer('status')->default(0);
$table->foreign('role_id')->references('id')->on('roles');
});
}
I've also added fillable:
protected $fillable = ['name', 'email', 'password', 'role_id', 'status'];
Now the issue is I cannot update "status" field and the operation doesn't return any issue. I already have tried it with different approaches. Have a look at the code and guide me. TIA.
public function update(Request $request, $id)
{
$validatedData = $request->validate([]);
// APPROACH # 1
$user = User::find($id);
$user->status = $request->status;
$user->save();
// APPROACH # 2
$user = User::find($id);
$user->update([
'status' => $request->status,
]);
// APPROACH # 3
User::findOrFail($id)->update($request->all());
}
Form:
<form action="{{ url('/admin/user') }}/{{ $editRecord[0]->id }}" method="POST" enctype="multipart/form-data">
#method('PUT')
#csrf
<select id="status" name="status" class="form-control">
<option value="1" #if($editRecord[0]->status == 1) selected #endif>Active</option>
<option value="0" #if($editRecord[0]->status == 0) selected #endif>In-Active</option>
</select>
</form>
Finally the route:
Route::put('/admin/user/{id}', 'Admin\PortalController#update');
Then code is working fine may be you forget to redirect back with success message. you should try below -
if($user->save()){
return redirect()->back()->with('message', 'updated successfully');
} else {
return redirect()->back()->with('error', 'something went wrong');
}
Then in blade file -
#if(session()->has('message'))
<div class="alert alert-success">
{{ session()->get('message') }}
</div>
#endif
#if(session()->has('error'))
<div class="alert alert-danger">
{{ session()->get('error') }}
</div>
#endif
I followed a nice tutorial on how to create roles and how to use gates with Laravel.
I can seed users with roles and edit them, but I would like to be able to create a user and give him/her one or more roles and I don't know where to start (I'm not a pro, but I need to finish this app).
Here's all the code I can show you so far :
Users Controller :
public function edit(User $user, $id)
{
$user = User::findOrFail($id);
$roles = Role::all();
return view('admin.users.edit',compact('user', 'roles'));
}
/**
* Update the specified resource in storage.
*
* #param \Illuminate\Http\Request $request
* #param \App\User $user
* #return \Illuminate\Http\Response
*/
public function update(Request $request, User $user, $id)
{
$user = User::findOrFail($id);
$user->roles()->sync($request->roles);
$user->name = $request->name;
$user->email = $request->email;
$user->save();
return redirect()->route('admin.utilisateurs.index');
}
Roles Table :
public function up()
{
Schema::create('roles', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
}
Pivot Table :
public function up()
{
Schema::create('role_user', function (Blueprint $table) {
$table->id();
$table->BigInteger('role_id')->unsigned()->onDelete('cascade');
$table->BigInteger('user_id')->unsigned()->onDelete('cascade');
$table->timestamps();
});
}
Edit blade file with checkboxes :
<div class="block-content">
<div class="form-group">
#foreach ($roles as $role)
<div class="form-group form-check">
<input type="checkbox" class="form-check-input" name="roles[]"
value="{{ $role->id }}" id="{{ $role->id }}"
#if ($user->roles->pluck('id')->contains($role->id)) checked #endif>
<label class="" for="{{ $role->id }}">{{ $role->name }}</label>
</div>
#endforeach
</div>
</div>
The thing is that I don't really know how to write my code on the Create Blade File.
Here's the create method on the controller (not sure if it's correct or not) :
public function store(Request $request, User $user)
{
$user = new User();
$user->roles()->sync($request->roles);
$user->name = $request->name;
$user->email = $request->email;
$user->save();
return redirect()->route('admin.utilisateurs.index')->with('success','Utilisateur ajouté');
}
Thanks for reading this long message!
Peace
on create blade it's almost as same as edit blade. you just need not to check for existing roles.
//rest of the form first like user name and email
<div class="block-content">
<div class="form-group">
#foreach ($roles as $role)
<div class="form-group form-check">
<input type="checkbox" class="form-check-input" name="roles[]" value="{{ $role->id }}" id="{{ $role->id }}">
<label class="" for="{{ $role->id }}">{{ $role->name }}</label>
</div>
#endforeach
</div>
</div>
and then in controller instead of sync just use attach
public function store(Request $request)
{
$user = new User();
$user->name = $request->name;
$user->email = $request->email;
$user->save();
$user->roles()->attach($request->roles);
return redirect()->route('admin.utilisateurs.index')->with('success','Utilisateurajouté');
}
look i have removed model binding in store function. it's not necessary in here. and attached roles after saving the user. docs on attach and sync in here.
im trying to do a little project with laravel 7 and have a question about creating and updating user roles.
Code in AdminUsersController.php:
public function create()
{
$roles = \App\Role::pluck('name', 'id')->all();
return view('admin.users.create', compact('roles'));
}
public function edit($id)
{
$user = User::findOrFail($id);
$roles = Role::pluck('name', 'id')->all();
return view('admin.users.edit', compact('user', 'roles'));
}
public function update(UpdateUsersRequest $request, $id)
{
$user = \App\User::findOrFail($id);
$user->update($input);
Session::flash('message', 'User successfully updated.');
return redirect(route('admin.users.index'));
}
Now if im using this blade-syntax in the view form for create and updating this works:
<div class="row">
<div class="col-sm-6">
<div class="form-group">
{!! Form::label('role_id', 'Role:') !!}
{!! Form::select('role_id', array('' => 'Choose Options') + $roles, null, ['class' => 'form-control']) !!}
</div>
</div>
</div>
But how can i do this without blade syntax? Is there a posibilty to pass the same array in the select tag?
i tried to loop through the $roles but didnt work:
<div class="form-group">
<select>
#foreach($roles as $role)
<option value="{{$role->id}}">{{role->name}}</option>
#endforeach
</select>
</div>
i mean i have a solution but i would like to if there is another option without blade syntax..
hope you can help me thank u :)
i have a users list & here i put a option to assign role to each users, for that when click 'Add Role' link it will show this route
Route::get('admin/home/role/{user}', 'RoleController#create');
in create function my form code is...
<form method="post" action="{{ url('admin/home/role') }}">
{{ csrf_field() }}
<div class="form-group">
<select name="role" class="form-control" >
<option value="1"> Admin </option>
<option value="2"> Editor</option>
</select>
</div>
<button type="submit" class="btn btn-primary">
Add Role
</button>
</form>
to manage this form my POST route is...
Route::post('admin/home/role', 'RoleController#store');
now how to insert this form request data into role_user table? oh! i have already 3 table, users, roles & role_user.
User model relationship code is...
public function role()
{
return $this->belongsToMany(Role::class, 'role_user');
}
Role model relationship code is...
public function user()
{
return $this->belongsToMany(User::class, 'role_user');
}
my question is how to insert form request data into role_user table?
i know one way that is...
public function store(Request $request, User $user)
{
$role = Role::find(1);
$user = User::find(19);
$role->user()->attach($user);
}
it works, but this is not dynamic. How to insert by form request? please help me. I searching about this topic tutorial but not found.
you need to send Role id and user id value to store function
public function store(Request $request)
{
$user_id=$request->input('user_id'); // get user id from post request
$role_id=$request->input('role_id'); // get Role id from post request
/* Todo request validation*/
$user = User::find($user_id);
$role = Role::find($role_id);
$user->roles()->attach($role);
}
view :
<form method="post" action="{{ action('RoleController#store') }}">
{{ csrf_field() }}
<input type="hidden" name="user_id" value="{{ $user->id }}" /> // you need to pass $user to this view
<div class="form-group">
<select name="role_id" class="form-control" >
<option value="1"> Admin </option>
<option value="2"> Editor</option>
</select>
</div>
<button type="submit" class="btn btn-primary">
Add Role
</button>
</form>