Shorter version of uuid as a primary key
Is there any way to generate shorter version of uuid as primary key
@tykus How about request validation it says failed.
@vidhyaprakash85 what do you mean it failed; what are you attempting to do?
@tykus I have encode the and sending the value to check whether it exists validation rule.
return [
'loan_officer' => ['required', 'exists:users,id'],
'loan_type' => ['required', 'exists:loan_types,id'],
'loan_purpose' => ['required', 'exists:loan_purposes,id'],
];
because of hashids request validation failed
@vidhyaprakash85 did you use one of the Hashids packages available; does it provide a custom exists validation rule?
If not, then you can create your own custom rule using the Model class and whatever trait method allows you to find a record by the hash id, e.g.
class ExistsHashId implements ValidationRule
{
public function __construct(string $modelClass)
{
$this->model = new $modelClass;
}
public function validate(string $attribute, mixed $value, Closure $fail): void
{
if (! $this->model->byHashId($value)->exists()) {
$fail("The $attribute does not exist on the $this->model->getTable().");
}
}
}
return [
'loan_officer' => ['required', new ExistsHashId(User::class)],
// etc.
];
@tykus So i have to create a new trait and include in the model class ?
@vidhyaprakash85 probably not. Did you use a package for Hash IDs?
@tykus yes i am using this https://github.com/mtvs/eloquent-hashids
@vidhyaprakash85 so now, because there is already a trait that you are using on the model 🤷♂️
If you write the Validation Rule class like I showed above, it should be working
@tykus ExistsHashId in which location i have to create this class.
Please guide me and also tell me whether i need to include in model as well.
@vidhyaprakash85 there is nothing needed in the Model class (except to use the HasHashid trait which I suppose you are already using). All you need to do is:
- Create the Rule class
php artisan make:rule ExistsHashId
- In
app/Rules/ExistsHashId.php, use the code I shared above. - In the FormRequest, change the
rulesmethod to return the array using theExistsHashIdRule instead (like I showed above
@tykus "Call to undefined method App\Models\User::byHashId()",
i am getting this error.
@vidhyaprakash85 did you apply the global scope from the package - HashidScope - in the relevant model(s)?
@tykus Yes i have added these two HasHashid, HashidRouting
@vidhyaprakash85 ok, so the trait should add that Global Scope; what is not working?
@tykus i added this is in the model
protected static function booted(): void
{
static::addGlobalScope(new HashidScope());
}
and my request
return [
'loan_officer' => ['required', new ExistsHashId(User::class)],
'loan_type' => ['required', 'exists:loan_types,id'],
'loan_purpose' => ['required', 'exists:loan_purposes,id'],
];
i have imported all the classes but still. i get this error
"Call to undefined method App\Models\User::byHashId()",
@tykus i found the error
if (! $this->model->byHashId($value)->exists()) {
$fail("The $attribute does not exist on the $this->model->getTable().");
}
to
if (! $this->model->byHashid($value)->exists()) {
$fail("The $attribute does not exist on the $this->model->getTable().");
}
but this error is coming after sorting out
"SQLSTATE[HY000]: General error: 1366 Incorrect integer value: 'VWxxxxxxxBZYk' for column 'loanofficer_id'
@vidhyaprakash85 the method in the scope is byHashid not byHashId
@vidhyaprakash85 the same Rule should be used anywhere you use a HashId in the Request
'loan_officer' => ['required', new ExistsHashId(User::class)],
'loan_type' => ['required', new ExistsHashId(LoanType::class)],
'loan_purpose' => ['required', new ExistsHashId(LoanPurpose::class)],
@tykus Error has gone but it is trying insert with hashid it is not converting to id.
"SQLSTATE[HY000]: General error: 1366 Incorrect integer value: 'VW4eGbBZYk' for column 'loanofficer_id'
@vidhyaprakash85 insert? So, you mean the foreign key is not being converted; what are you doing to convert from the Hash ID to the id?
@vidhyaprakash85 okay, then show the code you are using to create/update the record
public function first_step_create(StoreFirstStepBorrowerApplicationRequest $request): JsonResponse
{
try {
$borrowerApplication = DB::transaction(function () use ($request) {
$user = User::where('id', auth()->user()->id)->first();
return Borrower::create([
'loanofficer_id' => $request->loan_officer,
'loanpurpose_id' => $request->loan_purpose,
'loantype_id' => $request->loan_type,
'have_coborrower' => 0,
'first_name' => $user->first_name ?? null,
'middle_name' => '',
'last_name' => $user->last_name ?? null,
'user_id' => $user->id,
]);
});
return response()->json([
'status' => true,
'borrowerApplicationID' => $borrowerApplication->id,
'borrowerApplicationHashID' => $borrowerApplication->hashid,
], 200);
} catch (\Exception $exp) {
return response()->json([
'message' => $exp->getMessage(),
'status' => false
], 400);
}
}
@vidhyaprakash85 you need to decode the Hash ID wherever there is a Hash ID in the Request, e.g.
return Borrower::create([
'loanofficer_id' => (new LoanOfficer)->hashidToId($request->loan_officer),
'loanpurpose_id' => (new LoanPurpose)->hashidToId($request->loan_purpose),
'loantype_id' => (new LoanType)->hashidToId($request->loan_type),
'have_coborrower' => 0,
'first_name' => $user->first_name ?? null,
'middle_name' => '',
'last_name' => $user->last_name ?? null,
'user_id' => $user->id,
]);
@tykus Thank You.
@vidhyaprakash85 no problem
@vidhyaprakash85 I highly suggest that you don't use any kind of uuid as your primary key, they will slow your application down. You should use regular unsigned integers as your primary key. The reason for integers to be a better option is that they are indexable, which uuids are not.
@Tray2 you are absolutely right but to hide the numbers from user i am using this.
Have you considered snowflake ids as primary? Sortable, indexable, hard to guess, unique, only one id to deal with.
@schopin any example in what format it will be
Please or to participate in this conversation.