Laravel - custom id - laravel

I'm trying to make my custom ID for table posts. And I found haruncpi laravel id generator and I installed it with this command.
composer require haruncpi/laravel-id-generator.
After that I add use Haruncpi\LaravelIdGenerator\IdGenerator; to my PostsController. And now i need to add this snippet to my model.
$id = IdGenerator::generate(['table' => 'posts', 'length' => 10, 'prefix' =>'INV-']);
But I don't know where and how... Maybe in public function store() or somewhere else? Please help!
I just want my id to be like:
INV-000001
INV-000002
...

Laravel models has a boot() method, where you can register calls related to your model. Therefor you can subscribe to the creating event, which will fire before the model is saved and you can mutate the model in the process.
So in your Post.php model, add the following.
public static function boot()
{
parent::boot();
self::creating(function ($model) {
$model->id= IdGenerator::generate(['table' => 'posts', 'length' => 10, 'prefix' =>'INV-']);
});
}
And as long as you utilize basic Laravel functionality, it will add the id to the model.

Related

Laravel 9 Cannot UPDATE Data

CONTROLLER
public function update(Request $request)
{
DB::table('bahanbaku')->where('id', $request->id)->update([
'id_bb' => $request->id_bb,
'nama_bb' => $request->nama_bb,
'stok' => $request->stok
]);
dd($request);
return redirect('/bahanbaku');
}
Sorry for my bad english, but in my case,
After Submit, Data still same, not change
Can you help me? T.T
Id does not exist, this is quite basic, but i feel like there is some misunderstandings with Laravel. Just to get the basics down, in Laravel i would expect you to do the following.
Use models for database operations
Instead of passing the id on the request, pass it on URL parameters
Use model binding for getting your model.
Create your model, since it has a non standard table name define that. Add the properties you want to be filled when updating it as fillables.
use Illuminate\Database\Eloquent\Model;
class Bahanbaku extends Model {
protected $table = 'bahanbaku';
protected $fillables = [
'id_bb',
'nama_bb',
'stok',
];
}
In your route, define the model as a parameter.
Route::put('bahanbaku/{bahanbaku}', [BahanbakuController::class, 'update']);
Now the logic can be simplified to this, which will automatically handle if the model is not found and give you a 404 error.
public function update(Request $request, Bahanbaku $bahanbaku)
{
$bahanbaku->fill(
[
'id_bb' => $request->id_bb,
'nama_bb' => $request->nama_bb,
'stok' => $request->stok
],
);
$bahanbaku->save();
return redirect('/bahanbaku');
}
To improve even more, i would look into utilizing form requests.

Laravel Cashier - Class "App\Models\User" not found

When trying to cancel a subscription with Laravel Cashier, it returns the error:
Class "App\Models\User" not found
Code:
public function cancel(Request $request) {
$subscription = Auth::user()->subscription('default');
$subscription->cancel();
}
This is likely because my user model is not located at "App\Models\User" (the new default in Laravel 8), but rather it is located at "App\User".
In the official documents, it mentions this:
If you're using a model other than Laravel's supplied App\Models\User model, you'll need to publish and alter the Cashier migrations provided to match your alternative model's table name.
But this isn't the problem. My table name is the same, but the location of my model is different.
How do I fix this?
use App\User; // this is important in your case
use Laravel\Cashier\Cashier;
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
Cashier::useCustomerModel(User::class);
}
Docs: https://laravel.com/docs/8.x/billing#billable-model
Try change your providers config in config/auth.php
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
]
Reference https://laravel.com/docs/8.x/authentication#the-user-provider-contract

Laravel REST API and frontend

I created a project in Laravel, small database and added REST API in laravel to connect mobile app with database. What should I use to get data from database in web application? Using laravel models is easy but is that a good way to create another controllers to handle forms etc instead using rest api controllers? Thanks
Laravel also support for Restful API in own way.
for this
you create your controller in Api folder: php artisan make:controller Api/TestController
define your routes in routes/api.php :
Route::group(['namespace' => 'Api'], function (){
Route::group(['prefix' => '/test'], function () {
Route::get('/', 'TestController#list);
Route::get('/single', 'TestController#single');
});
});
create a resource collection for data that is an array of collection
php artisan make:resource Api/Collections TestCollection this command create a collection in folder app/Http/Resources/Api/Collections
open in and change toArray($request) function and add a function with($request) like following code :
public function toArray($request)
{
return $this->collection->map(function ($item){
return [
'id' => $item->id, // $item is instance of Test model
'name' => $item->name,
'description' => $item->description,
];
});
}
public function with($request) // optional : this method return with of response
{
return [
'status' => true
];
}
so go to TestController and create a method for get all tests:
public function list()
{
$tests = Test::all(); // your Test Model
return new TestCollection($test); // TestCollection you created above
}
this is return a json object that contains array of tests.
for get a single test :
php artisan make:resource Api/Resources TestResource
then go to TestResource in app/Http/Resources/Api/Collections and change code like following:
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name, // $this is instance of Test model
'description' => $this->description,
'body' => $this->body,
'diff_name' => $this->name_in_table // you can change the name differ from name in model instance
];
}
so go to TestController and create a method for single test
public function single(Request $request)
{
$test = Test::findOrFail($request->id);
return new TestResource($test);
}
this a summary of Rest API in laravel. Hope you find it useful
With laravel, you can reuse your api endpoints by taking advantage of the CreateFreshApiToken middleware.
Then you will only need to create new controllers and methods to display views. All of the CRUD stuff can be reused.

Laravel nova resource extending/overriding the create method

I am developing a web admin panel using Laravel Nova.
I am having an issue since Nova is quite a new technology.
What I would like to do now is I would like to add a hidden field or extend or override the create method.
This is my scenario. Let's say I have a vacancy nova resource with the following field.
public function fields(Request $request)
{
return [
ID::make()->sortable(),
Text::make('Title')->sortable(),
Text::make('Salary')->sortable()
// I will have another field, called created_by
];
}
Very simple. What I like to do is I want to add a new field called created_by into the database. Then that field will be auto filled with the current logged user id ($request->user()->id).
How can I override or extend the create function of Nova? How can I achieve it?
I can use resource event, but how can I retrieve the logged in user in
the event?
What you're looking for is Resource Events.
From the docs:
All Nova operations use the typical save, delete, forceDelete, restore Eloquent methods you are familiar with. Therefore, it is easy to listen for model events triggered by Nova and react to them.
The easiest approach is to simply attach a model observer to a model:
If you don't feel like creating a new observable you could also create a boot method in your eloquent model as so:
public static function boot()
{
parent::boot();
static::creating(function ($vacancy) {
$vacancy->created_by = auth()->user()->id;
});
}
But please do note that these are a bit harder to track than observables, and you or a next developer in the future might be scratching their head, wondering how's the "created_at" property set.
In my opinion you should go for Observers. Observers will make you code more readable and trackable.
Here is how you can achieve the same with Laravel Observers.
AppServiceProvider.php
public function boot()
{
Nova::serving(function () {
Post::observe(PostObserver::class);
});
}
PostObserver.php
public function creating(Post $post)
{
$post->created_by = Auth::user()->id;
}
OR
You can simply hack a Nova field using withMeta.
Text::make('created_by')->withMeta([
'type' => 'hidden',
'value' => Auth::user()->id
])
You could also do that directly within your Nova resource. Every Nova resource has newModel() method which is called when resource loads fresh instance of your model from db. You can override it and put there your logic for setting any default values (you should always check if values already exist, and only set if they are null, which will only be the case when the model is being created for the first time, which is what you actually need):
public static function newModel()
{
$model = static::$model;
$instance = new $model;
if ($instance->created_by == null) {
$instance->created_by = auth()->user()->id;
}
return $instance;
}
a) Create an Observer class with following command:
php artisan make:observer -m "Post" PostObserver
b) Add following code in the PostObserver:
$post->created_by = Auth::user()->id;
c) Register PostObserver in AppServiceProvider.php
For detailed explanation: https://medium.com/vineeth-vijayan/how-to-add-a-new-field-in-laravel-nova-resource-87f79427d38c
Since Nova v3.0, there is a native Hidden field.
Usage:
Hidden::make('Created By', 'created_by')
->default(
function ($request) {
return $request->user()->id;
}),
Docs: https://nova.laravel.com/docs/3.0/resources/fields.html#hidden-field

Laravel Model binding not working after upgrade to 5.3

I have Bind Model from Route service provider like this
class RouteServiceProvider extends ServiceProvider {
public function boot(){
parent::boot();
Route::model('job_title', \Cgs\Modules\JobTitle\Models\JobTitle::class);
}
}
and route likes this
Route::get('edit/{job_title}', ['as' => 'job.title.edit', 'uses' => 'JobTitleController#edit', 'middleware' => ['permission:job-title-edit']]);
Edit method
public function edit(JobTitle $jobtitle)
{
dd($jobtitle);
}
Above code give error
No query results for model [Cgs\Modules\JobTitle\Models\JobTitle]
When I check in debugger I see it is binding multiple times first correct and second it takes as json. Please help with multiple binding issue.

Resources