I am very much new to Laravel. During the learning curve I came across a situation which I am going to describe below :
I have a page contains data grid in /manage-clients route. For the grid I am used datatables. I have added edit button for each record. Now, I want to make the edit screen, which is basically a new view. I want the url structure for edit to be /manage-clients/edit/{id}. How to achieve this with the below set-up.?
below is my controller :
public function getIndex()
{
return View('admin.manageclients');
}
public function anyData()
{
$clients = DB::table('users')
->select(['id', 'first_name', 'last_name', 'email', 'created_at', 'updated_at'])
->where('type', '=', '');
return Datatables::of($clients)->addColumn('action', function ($clients) {
return '<i class="glyphicon glyphicon-edit"></i> Edit';
})->editColumn('id', 'ID: {{$id}}')->make(true);
}
public function editClient($id)
{
//This is my edit function which is going to load the details of provided $id into view.
return $id;
}
My route is :
Route::group (array('prefix' => 'admin', 'middleware' => 'auth'), function()
{
Route::get('dashboard',['as'=>'getDashboard', 'uses'=>'Admin\AdminController#getDashBoard']);
Route::controller('manage-admins', 'Admin\ManageAdminController', ['anyData' => 'manage-admins.data','getIndex' => 'manage-admins']);
Route::controller('manage-clients', 'Admin\ManageClientController', ['anyData' => 'manage-clients.data', 'getIndex' => 'manage-clients']);
});
Do you mean something like this?
Route::group (array('prefix' => 'admin', 'middleware' => 'auth'), function()
{
Route::get('dashboard',['as'=>'getDashboard', 'uses'=>'Admin\AdminController#getDashBoard']);
Route::controller('manage-admins', 'Admin\ManageAdminController', ['anyData' => 'manage-admins.data','getIndex' => 'manage-admins']);
Route::controller('manage-clients', 'Admin\ManageClientController', ['anyData' => 'manage-clients.data', 'getIndex' => 'manage-clients']);
Route::get('manage-clients/edit/{id}', 'ManageAdminController#editClient');//I have added this code
});
Note that id will be automatically be available to you inside the controller
Related
I have 2 views file for each 2 forms in one page , i can successfully add data from first form to database and read it but when i tried in second views, it gives 419 | PAGE EXPIRED error. I use same code i used in first views to add data.
this is my routes :
Route::group([
'prefix' => 'atribut',
'as' => 'atribut.'
], function () {
Route::group(['prefix' => 'tabHome', 'as' => 'tabHome.'], function () {
Route::get('', [AtributDashboardController::class, 'showTab'])->name('showTab');
Route::post('addDataFirst', [AtributDashboardController::class, 'addDataFirst'])->name('addDataFirst');
Route::get('deleteDataFirst/{id}', [AtributDashboardController::class, 'deleteDataFirst'])->name('deleteDataFirst');
Route::post('addDataSecond', [AtributDashboardController::class, 'addDataSecond'])->name('addDataSecond');
Route::get('deleteDataSecond/{id}', [AtributDashboardController::class, 'deleteDataSecond'])->name('deleteDataSecond');
});
});
This is my method in controller to add data:
public function __construct()
{
$this->inpDataFirst = new inpDataFirst ();
$this->inpDataSecond = new inpDataSecond ();
}
public function addDataFirst()
{
$data = [
'name' => Request()->nameForm,
'address' => Request()->addressForm,
];
$this->inpDataFirst->addData($data);
return redirect('atribut/tabHome');
}
public function addDataSecond()
{
$data = [
'name' => Request()->nameForm,
'address' => Request()->addressForm,
];
$this->inpDataSecond->addData($data);
return redirect('atribut/tabHome');
}
in first view i have form action :
{{route('frontend.atribut.tabHome.addDataFirst')}}
and in second view i have form action :
{{route('frontend.atribut.tabHome.addDataSecond')}}
the form is in same page but different views file, that's why i use return redirect
419 error is shown when csrf token is mismatched add #csrf to your form
My route:
Route::group([
'prefix' => '{locale}',
'where' => ['locale' => '[a-zA-Z]{2}'],
'middleware' => 'setlocale'],
function () {
// GROUP FOR AUTHENTICATION
Route::group([
'middleware' => 'auth:sanctum', 'verified',
], function () {
// GROUP FOR ADMIN
Route::group([
'prefix' => 'admin',
'as' => 'admin.',
], function () {
Route::resource('partner', PartnerFormController::class);
});
});
});
My view that when I click, it shows the details page:
Edit
My controller:
public function show(PartnerForm $partnerForm, $id)
{
$details = DB::table('partner_forms')->where('id', $id)
->first();
return view('admin.partner-details', compact('details'));
}
I tried to call $details->name or $details->in my view details page but it didnt work. The URL is working properly by displaying http://127.0.0.1:8000/en/admin/partner/1 but when i dd() my $id in controller it returns en, which I believe is the en from the URL.
Instead of sending the ID along with the route, send all the variables and enter the information into the new page in the control without the need to connect to the database and using route model binding.
Example :
view A
Foo
route
Route::get('.../{partner}', [Controller::class, 'Bar'])->name('admin.partner.show');
controller
public function Bar(Partner_MODEL $partner){
return view('view_name', compact('partner'));
}
view B : use $partner.
Important note : in (route, controller method, compact meethod) The variable name must be similar
I have a many-to-many pivot table (project_user) and am successful in getting all the projects of the authenticated user.
WriterController.php
public function writerProjects()
{
$projects = auth()->user()->projects;
dd($projects);
return view('writers.projects', compact('projects'));
}
web.php
Route::get('users/{user}/projects', ['as' => 'showProjects',
'uses' => 'WriterController#writerProjects']);
My question is how can I get the specific project's details? Here's my approach so far (it doesn't work though).
public function showWriterProjects($id)
{
$projects = auth()->user()->projects;
foreach($projects as $p)
{
dd($p->name);
}
return view('writers.projects.show', compact('projects'));
}
web.php for that
Route::get('users/{user}/projects/{project}', ['as' => 'showSingleProject',
'uses' => 'WriterController#showWriterProjects']);
What am I doing wrong?
Many-to-Many relations have been defined in User.php and Project.php, they seemed pretty obvious to post.
Since I'm not clear what is meant by "project's details", I'll go with project name.
Just imagine you only need 'name' attribute of 'projects'
Controller
public function showWriterProjects($id)
{
$project_names = auth()->user()->projects->map->name;
return view('writers.projects.show', compact('project_names'));
}
As we can read here, we can listen the eloquent events and use it in the AppServiceProvider. It goes like this:
public function boot()
{
User::creating(function ($user) {
Log::create(['message' => 'create method']);
});
User::deleting(function ($user) {
Log::create(['message' => 'delete method']);
});
}
For all my eloquent models, I want to log in the database when it is created and who created it. This would mean that I need to copy paste this snippet 20 times and only change the User::creating part.
Is there a way that I can catch the eloquent events from all models and make something like this:
public function boot()
{
AllModels::creating(function ($model) { // <--- something like this here?
Log::create([
'message' => 'create method',
'model' => get_class($model) // <--- and then get the class name
]);
AllModels::deleting(function ($user) {
/***/
}
});
}
You can try something like this:
$models = ['User', 'Post', 'Comment', ....];
foreach ($models as $model) {
$model::creating(....);
$model::deleting(....);
}
Similar approach worked for me (I used DI instead of facades though).
Another approach I found and bookmarked some time ago:
Event::listen(['eloquent.creating: *'], function() {
....
});
I'm trying to handle basic validation of my API calls in the Laravel's routes. Here is what I want to achieve:
Route::group(['prefix' => 'api/v1/properties/'], function () {
Route::get('purchased', 'PropertiesController#getPropertyByProgressStatus', function () {
//pass variable x = 1 to the controller
});
Route::get('waiting', 'PropertiesController#getPropertyByProgressStatus', function () {
//pass variable x = 2 to the controller
});
});
Long story short, depending on the segment of the URI after api/v1/properties/ I want to pass a different parameter to the controller. Is there a way to do that?
I was able to get it to work with the following route.php file:
Route::group(['prefix' => 'api/v1/properties/'], function () {
Route::get('purchased', [
'uses' => 'PropertiesController#getPropertyByProgressStatus', 'progressStatusId' => 1
]);
Route::get('remodeled', [
'uses' => 'PropertiesController#getPropertyByProgressStatus', 'progressStatusId' => 1
]);
Route::get('pending', [
'uses' => 'PropertiesController#getPropertyByProgressStatus', 'progressStatusId' => 3
]);
Route::get('available', [
'uses' => 'PropertiesController#getPropertyByProgressStatus', 'progressStatusId' => 4
]);
Route::get('unavailable', [
'uses' => 'PropertiesController#getPropertyByProgressStatus', 'progressStatusId' => 5
]);
});
and the following code in the controller:
public function getPropertyByProgressStatus(\Illuminate\Http\Request $request) {
$action = $request->route()->getAction();
print_r($action);
Pretty much the $action variable is going to let me access the extra parameter that I passed from the route.
I think that you can do it directly in the controller and receiving the value as a parameter of your route:
First you need to specify the name of the parameter in the controller.
Route::group(['prefix' => 'api/v1/properties/'], function ()
{
Route::get('{parameter}', PropertiesController#getPropertyByProgressStatus');
In this way, the getPropertyByProgressStatus method is going to receive this value, so in the controller:
class PropertiesController{
....
public function getPropertyByProgressStatus($parameter)
{
if($parameter === 'purchased')
{
//do what you need
}
elseif($parameter === 'waiting')
{
//Do another stuff
}
....
}
I hope it helps to solve your issue.
Take a view for this courses: Learn Laravel or Create a RESTful API with Laravel
Best wishes.
----------- Edited ---------------
You can redirect to the route that you want:
Route::group(['prefix' => 'api/v1/properties/'], function () {
Route::get('purchased', function () {
return redirect('/api/v1/properties/purchased/valueToSend');
});
Route::get('waiting', function () {
return redirect('/api/v1/properties/waiting/valueToSend');
});
Route::get('purchased/{valueToSend}', PropertiesController#getPropertyByProgressStatus);
});
Route::get('waiting/{valueToSend}', PropertiesController#getPropertyByProgressStatus);
});
});
The last two routes response to the redirections and send that value to the controller as a parameter, is the most near that I think to do this directly from the routes.