Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

CookieMonster's avatar

validation on multiple columns being unique?

I have a form to add a new rate to my Rates table and it has multiple columns. I want to be able to add a new rate but it should be unique, that is they should not exists in these three columns courier_id, weight and location_id.

So according to the docs, the validation unique is only to check uniqueness in a single column. So I tried using Rule to set it like below:

public function store(Request $request){
        $validated = $request->validate([
            'courier' => 'required', 
            'weight' => 'required|numeric',
            'location' => ['required',
            Rule::unique('rates')->where(function ($query) use($request) {
                return $query->where('courier_id', $request->courier)
                    ->where('weight', $request->weight)
                    ->where('location_id', $request->location);
            })
        ],
            'cost' => 'required|numeric',
            'hub_cost' => 'required|numeric'
        ]);

        dd($request->all());

    }

But everytime I try to add values that are already exist in the three columns, I get the error:

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'location' in 'where clause' (SQL: select count(*) as aggregate from `rates` where `location` = 1 and `courier_id` = 1 and `weight` = 1 and `location_id` = 1)

My table schema:

   Schema::create('rates', function (Blueprint $table) {
            $table->id();
            $table->integer('courier_id');
            $table->integer('weight');
            $table->decimal('cost', 5, 2);
            $table->integer('location_id');
            $table->timestamps();
        });
    }

I do not understand why it tries to query location as column since it is not supposed to be a column in the table. How do I make sure the three columns are unique?

0 likes
3 replies
SilenceBringer's avatar
Level 55

@nickywan123

Rule::unique('rates', 'location_id')->where(function ($query) use($request) {
                return $query->where('courier_id', $request->courier)
                    ->where('weight', $request->weight);
            })
1 like
CookieMonster's avatar

Why doesn't my original way works (since it is recommended by the docs the way of writing)?

Please or to participate in this conversation.