I’m using the package hashidshashids
to hash the ID of data sent through the URL (e.g …/post/bsdfs/edit, the ‘bsdfs’ is the encoded value). I followed Stuart Wagner‘s accessor method to do so. Below is how I do it:
use HashidsHashids;
class Post extends Model {
protected $appends = ['hashid'];
public function getHashidAttribute() {
$hashid = new Hashids(config('hash.keyword'));
return $hashid->encode($this->attributes['id']);
}
}
Before hashing the IDs I am getting post/2/edit
. After the hashing process, I’m getting post/bsdfs/edit
, which is fine to me.
The problem occurs when redirecting to the encoded route. This is how my route looks like:
use AppHttpControllersPostController;
Route::get('post/{post}/edit', '[email protected]')->name('post.edit');
After redirecting, I get a 404 error. This is what the controller accepts:
Use AppModelsPost;
class PostController extends Controller {
//PS: I don't actually know what this method is called...
public function edit(Post $post) {
return view('post.edit')->with(compact('post'));
}
}
I know that if I’m doing this method, Laravel is searching for an ID of ‘bsdfs’, which does not exist in the database. What it should do is decode the hash and get the ID. Is there a way to do it WITHOUT doing this:
public function edit($id) {
$hashid = new Hashids(config('hash.keyword'));
$id= $hashid->decode($id);
$post = Post::find($id);
return view('post.edit')->with(compact('post'));
}
As you can see, my goal here is to reduce the number of lines while still maintaining the data ID in the URL to be encoded. Any help would be appreciated. Thank you.
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
You could take advantage of Model Binding.
So your model should have something like this:
/**
* Retrieve the model for a bound value.
*
* @param mixed $value
* @param string|null $field
* @return IlluminateDatabaseEloquentModel|null
*/
public function resolveRouteBinding($value, $field = null)
{
$hashid = new Hashids(config('hash.keyword'));
return $this->findOrFail($hashid->decode($value)[0]);
}
So you can then have your controller like nothing happend:
public function edit(Post $post)
{
return view('post.edit')->with(compact('post'));
}
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0