Question

I have table named keywords as below

id  keyword syntax  description

I have a form that is used to edit KEYWORD details, i have the same validation rules on this form as i do on the create form as well as the database.

Basically the keyword has to be unique, but when updating if i just want to update the keywords details then it will fail and warn me that keyword already exists, so i cannot update the keyowords as their keyword has not been changed and thus throwing the database unique rule at me.

MY model class

public static $rules = array(

                                'keyword' => 'required|unique:keywords',
                                'syntax'=>'required',
                                'description'=>'required'
                                );
Était-ce utile?

La solution

To force the validator to ignore unique rule for a given id you may pass the id of that recored which is being validated, for example:

'keyword' => 'required|unique:keywords,keyword,10'

This, will not check uniqueness of the model if the id is 10, so when you are updating the model you need to pass the id of the current model to ignore the unique rule on this model:

'keyword' => 'required|unique:keywords,keyword,' . $id

Since your rules variable is public static $rules so you may access it from the controller and in this case before you run the validation in update method you need to change the rules for your keywords field and I think you can change the rule like this (just set new rules for that field):

// Replace the Model with the name of your model within the controller
// update method before the validation takes place
Model::$rules['keyword'] = 'required|unique:keywords,keyword,' . $id;

Check the documentation.

Autres conseils

You can do it in separate ways.

#1 An easy way is to use Ardent which takes care of this part . #2 When you edit, You can pass to Validator, a 'ignore id rule'

$rules = array(

                                'keyword' => 'required|unique:keywords,'.$id,
                                'syntax'=>'required',
                                'description'=>'required'
                                );

#3 A more complicated way is to use Validation as a service. Different rules based on different actions . When you will create the model, you will use the rules that you currently have.

When you will update the model, you will change the unique:keywords to exists:keywords

I usually do this with a validation service.

You create a base abstract Validator in services/ , which has a passes() function.

For each model, you create a ModelValidator , in your case CityValidator. Where you put your rules like :

public static $rules = array(
                           'new'=>[

                                'keyword' => 'required|unique:keyword',
                                'syntax'=>'required',
                                'description'=>'required'],
                           'edit'=>[
                                'keyword' => 'required|exists:keyword',
                                'syntax'=>'required',
                                'description'=>'required'
                                 ]
                                )

define Rules

class Dev extends \Eloquent

public static $rules = array(
    'id' => "required|min:1|max:999|unique:dev,id",
    'name' => 'required|min:2|max:32|unique:dev,name',
    'alias' => 'required|min:2|max:32|unique:dev,alias',
);

apply Rules

class TreeController extends \BaseController {

public function update($id)
{
    $rules = Dev::$rules;
    if ($id !== null) {
        $rules['id'] .= ",$id";
        $rules['name'] .= ",$id";
        $rules['alias'] .= ",$id";
    }

    $input = array_except(Input::all(), '_method');
    $v = Validator::make($input, $rules);

    if ($v->passes()) {
        $dev = $this->dev->find($id);
        try {
            $dev->update($input);
        } catch (Exception $e) {
            Session::flash('error', $e->getMessage());
        }
        return Redirect::route('adm.pattern.dev.index');
    } else {
        Session::flash('error', implode('<br />', $v->errors()->all(':message')));
        return Redirect::route('adm.pattern.dev.edit', $id)->withInput()->withErrors($v);
    }
}

}

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top