Livewire wire:model not working with nested components - php

I'm creating a page using livewire to list users from DB and be able to update them..
I have a Users parent component and (User)s child components
users.blade.php:
<div>
#foreach($users as $key => $user)
<livewire:user :user="$user" key="{{$user->id}}">
#endforeach
</div>
user.blade.php
<div>
<form wire:submit.prevent="save">
<input type="text" wire:model="user.name">
<input type="text" wire:model="user.email">
<button class="btn btn-info" type="submit">Save</button>
</form>
</div>
Users.php
class Users extends Component
{
public $users;
public function mount()
{
$this->users = User::all();
}
public function render()
{
return view('livewire.users');
}
}
User.php
class User extends Component
{
public $user;
public function mount(\App\Models\User $user)
{
$this->user = $user;
}
public function render()
{
return view('livewire.user');
}
protected $rules = [
'name' => 'required|min:6',
'email' => 'required|email',
];
public function save()
{
$this->validate();
$user = $this->user;
User::find($user['id'])->fill([
'name' => $user['name'],
'email' => $user['email']
]);
}
}
This is what i'm getting in the browser
Any idea why this is happening ?

I found the issue, it was the validation rules, I had to change it to
protected $rules = [
'user.name' => 'required|min:6',
'user.email' => 'required|email',
];

Related

Dropdown list in Laravel is not displaying

Below my drop-down list is not displaying and I don't know where the problem is. Could it be in my SerieController? I want to create an edit/update system but I've had no success.
SerieController
public function edit($id)
{
$series = Serie::with('marks')->find($id);
return view('admin.series.edit', compact('series'));
}
public function update(Request $request, $id)
{
$request->validate([
'name' => 'required',
'fk_mark' => 'required'
]);
$series = Serie::with('marks')->find($id);
$series->name = $request->get('name');
$series->fk_mark = $request->get('fk_mark');
$series->save();
return redirect()->route('series.index')
->with('success', 'updated successfully');
}
Mark Model
class Mark extends Model
{
protected $fillable = ['name_mark'];
public function series()
{
return $this->hasMany('App\Serie', 'fk_mark');
}
}
Serie Model
class Serie extends Model
{
protected $fillable = ['name', 'fk_mark'];
public function marks()
{
return $this->belongsTo('App\Mark', 'fk_mark');
}
}
I have another question. In my view, I have a form. Is the edit ok?
serie.index.blade
<form method="POST" action="{{ route('series.destroy', $serie) }}">
<a class="btn btn-sm btn-warning" href="{{ route('series.edit', $serie->id) }}">Editer</a>
</form>
I think it should be the other way: mark model belongsTo and Series model HasMany, no?

Laravel Policy (Too few arguments to function App\Policy)

I am trying to setup my policy for users. However I keep on getting an error of:
Too few arguments to function App\Policies\UserPolicy::update(), 1 passed in /vendor/laravel/framework/src/Illuminate/Auth/Access/Gate.php on line 481 and exactly 2 expected (View: /resources/views/users/index.blade.php)
ErrorException /app/Policies/UserPolicy.php 20
which is on the UserPolicy#update function
When I am logged in as super_admin, it works fine but it throws this error whenever I am logged in as a user of different role.
Below is my current implementation:
UserPolicy
class UserPolicy
{
use HandlesAuthorization;
public function update(User $user, User $userEdit) {
if ($user->id == $userEdit->id) {
return true;
}
return $user->can('update_user');
}
public function before($user, $ability) {
if ($user->hasRole('super_admin')) {
return true;
}
}
}
UsersController
class UsersController extends Controller {
public function __construct() {
$this->middleware('auth');
}
public function edit(User $user) {
$this->authorize('update', $user);
return view('users.edit', [
'user' => User::with('roles', 'level')->find($user->id),
'surveys' => \App\Survey::all(),
]);
}
public function update(UserRequest $request, User $user) {
$this->authorize('update', $user);
$request->save();
session()->flash('success', 'User successfully updated');
// means user is editing his own profile
if (auth()->id() == $user->id) {
return redirect('/dashboard');
} else {
return redirect('/users');
}
}
}
UserRequest
class UserRequest extends FormRequest {
public function authorize() {
return true;
}
public function rules() {
switch ($this->method()) {
case 'POST':
return [
'name' => 'required|string',
'email' => 'required|string|email|max:255|unique:users',
'role' => 'required|exists:roles,id',
'level' => 'required|string',
];
break;
case 'PATCH':
return [
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users,email,'.$this->user->id,
'role' => 'sometimes|exists:roles,id',
'level' => 'sometimes|string',
'password' => 'nullable|sometimes|string|min:6|confirmed'
];
break;
default:
break;
}
}
public function save() {
switch (request()->method()) {
case 'POST':
$this->createUser();
break;
case 'PATCH':
$this->updateUser();
break;
default:
break;
}
}
protected function createUser() {
// random generate password
$password = str_random(8);
$user = User::create([
'name' => request('name'),
'email' => request('email'),
'level_id' => request('level'),
'password' => Hash::make($password),
]);
$user->assignRoleById(request('role'));
Mail::to($user)->send(new WelcomeMail($user, $password));
}
protected function updateUser() {
$user = User::findOrFail($this->user->id);
$user->name = request('name');
$user->email = request('email');
if (request('password') != '') {
$user->password = Hash::make(request('password'));
}
if (request('level') != '') {
$user->level_id = request('level');
}
$user->update();
if (request('role') != '') {
$user->roles()->sync([request('role')]);
}
}
}
AuthServiceProvider
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* #var array
*/
protected $policies = [
\App\User::class => \App\Policies\UserPolicy::class,
];
/**
* Register any authentication / authorization services.
*
* #return void
*/
public function boot()
{
$this->registerPolicies();
foreach ($this->getPermissions() as $permission) {
Gate::define($permission->name, function($user) use ($permission) {
return $user->hasRole($permission->roles);
});
}
}
protected function getPermissions() {
return Permission::with('roles')->get();
}
}
In my views file I'm calling
#can('update', App\User::class)
<!-- html code --!>
#endcan
instead of
#can('update', $user)
<!-- html code --!>
#endcan
I was not passing the user instance into the function which was causing the error.
In UserRequest you haven't given any parameters when you call $user->update();. The update() function requires for a UserRequest instance, as well as a User.
Give this a try: $user->update(request()->all(), $user)
Edit:
I would just move the following...
$this->authorize('update', $user);
$request->save();
session()->flash('success', 'User successfully updated');
// means user is editing his own profile
if (auth()->id() == $user->id) {
return redirect('/dashboard');
} else {
return redirect('/users');
}
...to the updateUser() function.

Merge 2 rules FormFequest for validate an update and store action in laravel5.5

I have 2 FormRequest classes (ReadersFormRequest, SocialMediaFormRequest) and I want to store and update a Reader. A Reader may have 0 or many social media accounts, so it's necessary to validate the request.
ReadersFormRequest
class ReadersFormRequest extends FormRequest
{
public function rules()
{
return [
'first_name'=>'required',
'last_name'=>'required',
'birthday'=>'required',
'region'=>'required',
'photo_url'=>'required',
'support'=>'required',
'riwayas_id'=>'required',
'description'=>'required',
];
}
}
SocialMediaFormRequest
public function rules()
{
return [
'url'=>'required|url',
'title'=>'required'
];
}
So I want to merge the SocialMediaFormRequest rules in ReadersFormRequest rules
I found a solution:
make SocialMediaFormRequest rules a static method and merge it in SocialMediaFormRequest rules
SocialMediaFormRequest
public static function rules()
{
return [
'url'=>'required|url',
'title'=>'required'
];
}
ReadersFormRequest
public function rules()
{
return array_merge(SocialMediaFormRequest::rules(),[
'first_name'=>'required',
'last_name'=>'required',
'birthday'=>'required',
'region'=>'required',
'photo_url'=>'required',
'support'=>'required',
'riwayas_id'=>'required',
'description'=>'required',
]);
}
I think the merge is correctly done, but in update controller when I call this ReadersFormRequest, I don't know what happens.
public function update(ReadersFormRequest $request, Readers $reader)
{
// valid and update reader
Readers::whereId($reader->id)->update([
'first_name' => $request->validated()['first_name'],
'last_name' => $request->validated()['last_name'],
'photo_url' => $request->validated()['photo_url'],
'birthday' => $request->validated()['birthday'],
'region' => $request->validated()['region'],
'support' => $request->validated()['support'],
'riwayas_id' => $request->validated()['riwayas_id'],
'description' => $request->validated()['description']
]);
// For update their social media account links
foreach ($request->validated()['url'] as $key => $url)
{
}
return redirect(route('readers.show',$reader));
}
When I PUT the reader form this controller is not called.
Alter your class to:
class ReadersFormRequest extends FormRequest
{
public function rules()
{
return [
'first_name'=>'required',
'last_name'=>'required',
'birthday'=>'required',
'region'=>'required',
'photo_url'=>'required',
'support'=>'required',
'riwayas_id'=>'required',
'description'=>'required',
'url'=>'required|url',
'title'=>'required'
];
}
}
or if you really want to use a class do:
class ReadersFormRequest extends FormRequest
{
public function rules(SocialMediaFormRequest $social)
{
$mediaRules = $social->rules();
$rules = [
'first_name'=>'required',
'last_name'=>'required',
'birthday'=>'required',
'region'=>'required',
'photo_url'=>'required',
'support'=>'required',
'riwayas_id'=>'required',
'description'=>'required',
];
return array_merge($rules,$mediaRules);
}
}
This's how I handled it in similar situation:
public static function combineValidations($rules1, $rules2)
{
if(!is_array($rules2)) return $rules1;
foreach($rules2 as $key => $item)
{
if(!isset($rules1[$key]))
{
$rules1[$key] = $item;
}else
{
$rules1[$key] .= '|'.$item;
}
}
return $rules1;
}

"Undefined variable" in laravel 5.2 view

I'm getting a undefined variable error in my view if I include this route with a parameter:
<div class="table-toolbar">
<div class="row">
<div class="col-md-6">
<div class="btn-group">
<i class="fa fa-plus"></i> Add new
</div>
</div>
</div>
</div>
Here's my full controller for that given view:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Model\CampusMajor;
use App\Model\CampusMajorsFacilities;
class CampusMajorsFacilitiesController extends Controller
{
//
public function index($campusMajorId)
{
$campusMajorsFacilities = CampusMajorsFacilities::ofCampusMajor($campusMajorId)->get();
$data = [
'campusMajorsFacilities' => $campusMajorsFacilities,
'campusMajor' => $campusMajorId
];
return view('major-facilities.index', $data);
}
public function add($campusMajorId)
{
$campusMajorsFacilities = new CampusMajorsFacilities;
$data = [
'campusMajorsFacilities' => $campusMajorsFacilities,
'campusMajorId' => $campusMajorId,
'formIs' => 'add'
];
return view('major-facilities.form', $data);
}
public function save(Request $request,$campusMajorId)
{
$this->validation($request);
$post = $request->all();
$campusMajorsFacilities = $this->bindToObject($post,$campusMajorId);
$campusMajorsFacilities->save();
return redirect()->route('major-facilities.index', $campusMajorId)->with('message','Item added Succesfully');
}
public function edit($campusMajorId, $id)
{
$campusMajorsFacilities = CampusMajorsFacilities::find($id);
$data = [
'campusMajorsFacilities' => $campusMajorsFacilities,
'campusMajorId' => $campusMajorId,
'formIs' => 'edit'
];
return view('major-facilities.form', $data);
}
public function update(Request $request,$campusMajorId,$id)
{
$this->validation($request);
$post = $request->all();
$campusMajorsFacilities = $this->bindToObject($post,$campusMajorId,$id);
$campusMajorsFacilities->save();
return redirect()->route('major-facilities.index', $campusMajorId)->with('message','Item updated Succesfully');
}
private function validation($request)
{
$this->validate($request,[
'title' => 'required',
'description' => 'required',
'content' => 'required',
'campus_major_id' => 'required'
]);
}
public function delete($campusMajorId,$id)
{
$campusMajorsFacilities = CampusMajorsFacilities::find($id);
$campusMajorsFacilities->delete();
return redirect()->route('major-facilities.index', $campusMajorId)->with('message','Item deleted Succesfully');
}
private function bindToObject($post,$campusMajorId,$id=null)
{
if(is_null($id)){
$campusMajorsFacilities = new CampusMajorsFacilities;
} else {
$campusMajorsFacilities = CampusMajorsFacilities::find($id);
}
$campusMajorsFacilities->major_campus_id = $campusMajorId;
$campusMajorsFacilities->title = $post['title'];
$campusMajorsFacilities->description = $post['description'];
$campusMajorsFacilities->content = $post['content'];
return $campusMajorsFacilities;
}
}
And my model
<?php
namespace App\Model;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class CampusMajorsFacilities extends Model
{
//
use SoftDeletes;
public function CampusMajor()
{
return $this->belongsTo('App\Model\CampusMajor');
}
public function scopeOfCampus($query, $campus_id)
{
return $query->where('campus_id', $campus_id);
}
public function scopeOfCampusMajor($query, $campus_major_id)
{
return $query->where('campus_major_id', $campus_major_id);
}
}
If I comment out the route I passed the view just fine, I don't know where I went wrong.
You have passed $campusMajorId from controller to view as campusMajor only, not as campusMajorId.
Hence the variable is undefined in the view.

remember_token missing when add user in laravel 5.2

hello i want to add user when admin log in. i use default Register form.
it success but remember_token is missing and parssword not decrypt.
this is my controller :
public function create()
{
return view('admin/dosen.create');
}
public function store(CreateDosenRequest $request)
{
User::create($request->all());
return redirect('admin/dosen')->with('message', 'Data berhasil ditambahkan!');
}
and my request :
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'name' => 'required|max:255',
'username'=>'required|unique:users',
'email' => 'required|email|max:255|unique:users',
'password' => 'required|confirmed|min:6',
];
}
Route :
Route::resource('/admin/dosen', 'AdminController',
['except => show, index']);
});
<form method="post" action="#"><input type="hidden" name="_token" value="{{csrf_token()}}"></form>
Just add this in html form.Working :)

Categories