8

I know this question has been asked earlier but i did not get relevant answer.

I want to know that how can i write a rule to check uniqueness of two columns. I have tried to write a rule like:

public $rules = array(
    "event_id"=>"required",
    "label"=>"required|unique:tblSection,label,event_id,$this->event_id",
    "description"=>"required"
);

In my example i need to put validation so that one label could be unique for a single event id but may be used for other event id as well. For Example i want to achieve:

id   event_id    label   description
1     1          demo    testing
2     2          demo    testing

In the rule defined above, somehow i need to pass current selected event_id so that it could check whether the label does not exist in the database table for selected event_id but i am getting syntax error like:

{"error":{"type":"Symfony\\Component\\Debug\\Exception\\FatalErrorException","message":"syntax error, unexpected '\"'","file":"\/var\/www\/tamvote\/app\/modules\/sections\/models\/Sections.php","line":39}}

Note: I don't want to use any package but simply checking if laravel 4 capable enough to allow to write such rules.

5 Answers 5

10

The answer from Mohamed Bouallegue is correct.

In your controller for the store method you do:

Model::$rules['label'] = 'required|unique:table_name,label,NULL,event_id,event_id,' .$data['event_id'];

where $data is your POST data.

And for the update method you do:

$model = Model::find($id);
Model::$rules['label'] = 'required|unique:table_name,label,NULL,event_id,event_id,'.$data['event_id'].',id,id'.$model->id;

where $data is your PUT/PATCH data, $model is the record you are editing and id is the table primary key.

Sign up to request clarification or add additional context in comments.

Comments

2

I didn't try this before but I think if you get the event_Id before validating then you can do it like this:

'label' => 'unique:table_name,label,NULL,event_id,event_id,'.$eventId
//you should get the $eventId first

3 Comments

It generates an error "{"error":{"type":"Symfony\\Component\\Debug\\Exception\\FatalErrorException","message":"syntax error, unexpected '.', expecting ')'","file":"\/var\/www\/tamvote\/app\/modules\/sections\/models\/Sections.php","line":40}}"
how can i get eventid first because the above statement is going to be written in $rules array that is just a public variable in the model.
if you create the rules array in your controller then you can get the event_id and concatenate it to the rules
2

If you want to declare your validation rules statically you can do this as well. It's not the most efficient since it checks the database for each value.

protected $rules = [
    'user_id' => 'unique_multiple:memberships,user_id,group_id',
    'group_id' => 'unique_multiple:memberships,user_id,group_id',
]

/**
 * Validates that two or more fields are unique
 */
Validator::extend('unique_multiple', function ($attribute, $value, $parameters, $validator)
{
    //if this is for an update then don't validate
    //todo: this might be an issue if we allow people to "update" one of the columns..but currently these are getting set on create only
    if (isset($validator->getData()['id'])) return true;

    // Get table name from first parameter
    $table = array_shift($parameters);

    // Build the query
    $query = DB::table($table);

    // Add the field conditions
    foreach ($parameters as $i => $field){
        $query->where($field, $validator->getData()[$field]);
    }

    // Validation result will be false if any rows match the combination
    return ($query->count() == 0);

});

Comments

0

Like Sabrina Leggett mentioned, you need to create your own custom validator.

Validator::extend('uniqueEventLabel', function ($attribute, $value, $parameters, $validator) {
    $count = DB::table('table_name')->where('event_id', $value)
                                    ->where('label', $parameters[0])
                                    ->count();

    return $count === 0;
}, 'Your error message if validation fails.');

You can call your validator by adding the following line to your rules:

'event_id' => "uniqueEventLabel:".request("label")

If you need more fields, you could add a new where clause to the sql statement.

(Source: edcs from this answer)

Comments

0

As you I was looking for hours to do that but nothing worked, I test everything ... suddenly the randomness of the doc I came across this:

'email' => Rule::unique('users')->where(function ($query) {
              return $query->where('account_id', 1);
           })

https://laravel.com/docs/5.5/validation#rule-unique

and it works perfectly and moreover it is very flexible :)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.