Create unique constraint with two fields in Laravel request

4

I have in the creation migration of my table the following:

public function up()
    {
        Schema::connection('database2')->create('empresa_funcoes', function(Blueprint $table) {
            $table->increments('id');
            $table->integer('empresa_id')->unsigned();
            $table->integer('funcao_id')->unsigned();
            $table->timestamps();

            //Create a Unique Constraint
            $table->unique(['empresa_id', 'funcao_id'], 'empresa_funcao');

            //Create Foreign Keys
            $table->foreign('empresa_id')->references('id')->on('empresas')->onDelete('cascade');
            $table->foreign('funcao_id')->references('id')->on('funcoes')->onDelete('cascade');

        });
    }

In my request I need to create a constraint so that I can not register a 2x function for the same company.

I have this so far in my CompanyFunctionRequest, but I can not just put a unique there because it will not let me register that role for another company.

public function rules()
    {
        return [
            'funcao_id' => 'required',
        ];
    }

What can I do?

  

I'm not asking to validate the empresa_id because it's going on a   hidden, I do not know if it influences.

    
asked by anonymous 06.10.2016 / 16:49

1 answer

3

Create a custom validation rule because, as your case is particular, I gave a look at the current rules, I do not think any can do what you need, maybe in parts, so make your own rule by first creating a Service Provider :

  

php artisan make:provider UniqueKeyDupleServiceProvider

In the app/Providers folder, edit the created file: UniqueKeyDupleServiceProvider :

<?php

namespace App\Providers;

use App\Models\EmpresaFuncao;
use Illuminate\Support\ServiceProvider;


class UniqueKeyDupleServiceProvider extends ServiceProvider
{


    public function boot()
    {
        \Validator::extend('uniquekeyduple', 
                    function($attribute, $value, $parameters, $validator)
        {
            $value1 = (int)request()->get($parameters[0]);
            if (is_numeric($value) && is_numeric($value1))
            {
                return (!(EmpresaFuncao::where($attribute, $value)
                    ->where($parameters[0], $value1)
                    ->count() > 0));
            }
            return false;
        });
    }

    public function register()
    {
        //
    }
}

Within this Service Provider was added an custom validation and inside has model EmpresaFuncao who does the search to find out if there is a record for a particular company if the function has already been registered . If it already exists it does not let go and does not perform the method that is used this rule.

After creating register your providers as follows : in file config/app.php it goes to the array of providers and add this new provider as follows:

'providers' => [
    // Other Service Providers

    App\Providers\UniqueKeyDupleServiceProvider::class,
],

In the function request ( EmpresaFuncaoRequest ) add the rule created with the name of uniquekeyduple as a parameter the field funcao_id , being: uniquekeyduple:funcao_id , follow code example:

<?php

namespace App\Http\Requests;    
use Illuminate\Foundation\Http\FormRequest;

class EmpresaFuncaoRequest extends FormRequest
{

    public function authorize()
    {
        return true;
    }

    public function rules()
    {
        return [
            'empresa_id' => 'required|uniquekeyduple:funcao_id'
        ];
    }

    public function messages()
    {
        return [
            'empresa_id.uniquekeyduple' => 'Função existente!'
        ];
    }
}

Finishing on Controller

<?php

namespace App\Http\Controllers;

use App\Http\Requests\EmpresaFuncaoRequest;
use App\Http\Requests;

class EmpresaFuncaoController extends Controller
{
    public function index()
    {
        return view('empresafuncao');
    }

    public function store(EmpresaFuncaoRequest $request)
    {
        //faça as operações que assim desejar
        return $request->all();
    }
}

06.10.2016 / 18:12