0

I was doing great so far until I ran into another problem with validation. I'm trying to update a user related table called socialLinks. The problem is every time I update, since it's a model backed form, the prefilled values in the form gets pass through validations and I get a 'has already been taken' error in return.

After doing a bunch of googling, I tried to pass userId through update, but i haven't had any success. I had this problem before but I was validating a column from User. Now I'm trying to validate a column from another table with a relationship with user and nothing I tried before works. Super Frustrating.

my form

{!! Form::model($user_links,['method' => 'PATCH', 'action'=> ['UserController@update_social']]) !!}
                <div class='row form-group'>
                    <div class='col-md-2'>
                        {!! Form::label('facebook', 'Facebook Username') !!}
                    </div>
                    <div class='col-md-7'>
                        {!! Form::text('facebook', null,['class'=>'form-control']) !!}
                    </div>
                </div>
                <div class='row form-group'>
                    <div class='col-md-2'>
                        {!! Form::label('twitter', 'Twitter Username') !!}
                    </div>
                    <div class='col-md-7'>
                        {!! Form::text('twitter', null,['class'=>'form-control']) !!}
                    </div>
                </div>
                <div class='row form-group'>
                    <div class='col-md-2'>
                        {!! Form::label('reddit', 'Reddit Username') !!}
                    </div>
                    <div class='col-md-7'>
                        {!! Form::text('reddit', null,['class'=>'form-control']) !!}
                    </div>
                </div>
                <div class='row form-group'>
                    <div class='col-md-3'>
                        {!! Form::submit('Save Changes',['class'=>'btn btn-md btn-success']) !!}
                {!! Form::close() !!}

routes

Route::get('/account/social','UserController@social');
    Route::patch('/account/social','UserController@update_social');

and controllers

public function social(Request $request){
  $user = $request->user();
  $user_links= $request->user()->links;
  return view('user.edit.social_connect',compact('user_links','user'));
}

public function update_social(Request $request){

  $user = $request->user();
  $validator=Validator::make($request->all(),[
            'facebook' => 'unique:social_links,facebook,'.$user->id,
            'twitter' => 'unique:social_links,twitter'.$user->id, 
            'reddit' => 'unique:social_links,reddit,'.$user->id,
            'google' => 'unique:social_links,google,'.$user->id        
    ]);
  if ($validator->fails()){
    var_dump($user->id);exit;
    return Redirect::back()->withErrors($validator)->withInput();
  }

  $data=Input::all();
  $links = $user->links;
  if ($links == null){
    $links = new SocialLinks();
    $links->fill($data);
    $links->user_id=$user->id;
    $links->save();
  }else{
    $links->fill($data);
    $links->save();
  }
  return Redirect::back()->with('message','Your profile has been updated');     
}

Update put validation logic in controller

jackjoesmith
  • 951
  • 4
  • 20
  • 33

3 Answers3

1

this is what worked for me

  $user = $request->user();
  $id = $user->id;
  $validator=Validator::make($request->all(),[
            'facebook' => 'unique:social_links,facebook,'.$id.',user_id',
            'twitter' => 'unique:social_links,twitter,'.$id.',user_id', 
            'reddit' => 'unique:social_links,reddit,'.$id.',user_id',
            'google' => 'unique:social_links,google,'.$id.',user_id',        
    ]);

I honestly don't get why though. Why do we concatenate id to exclude it from being validated? the syntax makes no sense to me. Also $id comes from user object, and 'user_id' is from my social links table. Am I matching ids here? Somebody please show me the light ;(

jackjoesmith
  • 951
  • 4
  • 20
  • 33
0

To start: In general, extending the Laravel Request class and dependency injecting your extended class into your controller functions, although it can be done, is a bad idea. Read this to understand why (although it may not appear to be related at first read):

Laravel 5 / Codeception not routing correctly

Basically the problem is that if your validation class throws a perfectly legitimate validation exception, that exception has to be trapped by the Laravel router and not by the controller function. Essentially unless the validation passes your controller function never gets called, and so it can't trap the validation exception. This frequently results in either a 500 error or a redirect to a completely different page (which is why this screws up codeception tests amongst other unwanted side-effects).

So a better plan is to pass a Laravel Request object into your controller function and validate inside the function, rather than attempting to get Laravel to do it for you.

Once you resolve that issue, getting the validation code to handle the case where the $user does not exist should be easy. Some suggestions for your validation code to handle that validation (which should now be inside your controller function, or in a separate validator class called from your controller function):

  • Request probably doesn't contain a User object. It might contain a user_id variable which you can turn into a User object using User::find($user_id) or similar.

  • Check to ensure that $user is not null before attempting to work with $user->id or you'll get an error. If the $user_id passed in is empty or invalid then User::find($user_id) will return null. Check for this case and throw an exception first, before you continue to look at $userId or save any links.

I can't see exactly what you're doing in your form but if the above doesn't resolve your issues then post the form here and we can take another look.

Community
  • 1
  • 1
delatbabel
  • 3,601
  • 24
  • 29
0

You need to edit validation for updating, this is my example from one app :

public function rulesAdmin($id = NULL)
{
    return [
        'name'  => 'required|min:5',
        'username' => 'unique:users' . ($id ? ",username, $id" : ''),
    ];
}

on editing ->you pass from database $id, on saving new record -> $id is NULL.

fico7489
  • 7,931
  • 7
  • 55
  • 89
  • i get 'Undefined offset: 1' error. I'm doing the validation in my controller so I didn't pass $id = Null into the arg. I just set id before validation. Does it matter? – jackjoesmith Oct 14 '15 at 13:03
  • on editing ->you pass from database $id, on saving new record -> $id is NULL. – fico7489 Oct 14 '15 at 18:15