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'));
}
Related
I tried looking for all the possible solutions none of it worked and this is very basic trying to send data from a controller to view in Laravel.
Paymentcontroller
public function payment() {
$plans =[
'Basic' => "Monthly"
];
$intent = $user->createSetupIntent();
return view('pages.subscription', compact('intent', 'plans'));
}
PageController
public function index(string $page)
{
if (view()->exists("pages.{$page}")) {
return view("pages.{$page}");
}
return abort(404);
}
View pages.subscription
<div>
{{ $intent }}
</div>
route
Route::get('{page}', ['as' => 'page.index', 'uses' => 'PageController#index']);
Route::get('/subscription', 'PaymentController#payment');
This makes the page work but doesn't display the data
Move Route::get('/subscription', 'PaymentController#payment'); before Route::get('{page}',.... (it should be your last route in the list).
Currently when you call /subscription endpoint you are calling PageController#index, but it doesn't contain logic of your PaymentController#payment and doesn't pass any data to view.
I have a controller in Laravel 5.
I would like to write a controller function that accepts variable arguments.
For example,
public function show(Request $request, ...$id)
{
// handle multiple $id values here
}
The reason is that I have a url structure that has 'nested' models.
For instance:
\item\{$id}
\parent\{$parent_id}\item\{$id}
\grandparent\{$grandparent_id}\parent\{$parent_id}\item\{$id}
The routes are defined as:
Route::resource('item', 'ItemController');
Route::resource('parent.item', 'ParentController');
Route::resource('grandparent.parent.item', 'GrandparentController');
My desire is to write a single show() method as a trait that each controller can use.
Because of the structure of my database, it is possible.
But the UrlGenerator keeps throwing a UrlGenerationException when I try to use variable arguments. It seems like it doesn't understand this construct?
Ok, here's an idea for you that should get you on the right path:
For the various resource routes you defined, re-declare them to exclude the 'show' action, and define a separate GET route to map the routes you are trying to centralise.
app/Http/routes.php:
Route::resource('item', 'ItemController', ['except' => ['show']]);
Route::get('item/{item}', ['uses' => 'AggregateController#handleShow', 'as' => 'item.show']);
Route::resource('parent.item', 'ParentController', ['except' => ['show']]);
Route::get('parent/{parent}/item/{item}', ['uses' => 'AggregateController#handleShow', 'as' => 'parent.item.show']);
Route::resource('grandparent.parent.item', 'GrandParentController', ['except' => ['show']]);
Route::get('grandparent/{grandparent}/parent/{parent}/item/{item}', ['uses' => 'AggregateController#handleShow', 'as' => 'grandparent.parent.item.show']);
app/Http/Controllers/AggregateController.php:
class AggregateController extends Controller
{
public function handleShow(Request $request, ...$items)
{
dd($request->path(), $items);
}
}
http://stackoverflow42005960.dev/grandparent/1/parent/2/item/3:
"grandparent/1/parent/2/item/3"
array:3 [▼
0 => "1"
1 => "2"
2 => "3"
]
If you still have issues with getting the variable arguments, then check your PHP version and if < 5.6 you'll have to use func_get_args()
There're many ways to go about this. For example, you can use a comma separated list in routes and simply explode in controller.
The way you have it currently, you will have to use a fixed number of optional parameters, e.g.
public function show(Request $request, $id1, $id2 = false, $id3 = false)
{
//if parent item exists
if($id2)
{
//if grandparent item resource
if($id3)
{
}
}
else
{
//just item
}
}
i want to make edit-update function..
this is my code :
Admin Controller
public function edit_ist($id_prog)
{
$program_studi = ProgramStudi::find($id_prog);
return view('edit_ist_program_studi',compact('program_studi'));
}
public function update_ist($id_prog)
{
$istUpdate = Request::all();
$program_studi = ProgramStudi::find($id_prog);
$program_studi->update($istUpdate);
return redirect('administrator');
}
Form open in view edit_ist_program_studi
{{ Form::model($program_studi,['method'=>'PATCH','route'=>['update_prodi',$program_studi->id_prog]])}}
Routes:
Route::patch('admin_page/edit_prodi/{id_prog}',
['as' => 'update_prodi', 'uses' => 'AdminController#update_ist']);
But i found error NotFoundHttpException, can you help me to fix this ? thank you
You are missing the GET route to the edit page.
Add something like this:
Route::get('admin_page/edit_prodi/{id_prog}', ['as' => 'edit_prodi', 'uses' => 'AdminController#edit_ist']);
So basically my app has two types of dynamic url..
app.com/{page}
app.com/{user}
Both having their own controllers
PageController#index
User\ProfileController#index
But I'm struggling to get this working.
I have tried a few different methods. Here are two I have tried..
Route::get('{slug}', function($slug) {
if (App\Page::where('slug', $slug)->count()) {
// return redirect()->action('PageController#index', [$slug]);
// return App::make('App\Http\Controllers\PageController', [$slug])->index();
return 'Page found';
} else if (App\User::where('username', $slug)->count()) {
// return redirect()->action('User\ProfileController#index', [$slug]);
// return App::make('App\Http\Controllers\User\ProfileController', [$slug])->index();
return 'User found';
} else {
return abort(404);
}
});
I feel I should be doing this with middleware/filters. Any help would be great. Thanks.
I think you could achieve what you after with Route::group using a middleware to filter if it is a page or a user.
Route::group(['middleware' => 'isPage'], function () {
Route::get('{slug}', ['as'=> 'pages.show', 'uses' => 'PageController#show']);
});
Route::group(['middleware' => 'isUser'], function () {
Route::get('{slug}', ['as'=> 'users.show', 'uses' => 'User\ProfileController#show']);
});
If you were using slugs for the Pages and ids for the Users, your idea of handling the issue might make more sense, but since you are using slugs for both the pages and the users, I strongly suggest you try a different approach. Why not declare two routes? Why not use the "show" methods of the respective controllers while you are at it, and keep in line with conventions for resources?
Route::get('pages/{slug}', ['as'=> 'pages.show', 'uses' => 'PageController#show']);
Route::get('users/{slug}', ['as'=> 'users.show', 'uses' => 'User\ProfileController#show']);
And if you really want to keep your "root-slug-respective-redirect" functionality you could write afterwards:
Route::get('{slug}', function($slug) {
if (App\Page::where('slug', $slug)->count()) {
return redirect(route('pages.show', $slug));
} else if (App\User::where('username', $slug)->count()) {
return redirect(route('users.show', $slug));
}
return abort(404);
});
I do advise against it though, as it seems like a waste of queries.
Here are the docs on Laravel RESTful resource controllers for good measure.
I am using Hashid to hide the id of a resource in Laravel 5.
Here is the route bind in the routes file:
Route::bind('schedule', function($value, $route)
{
$hashids = new Hashids\Hashids(env('APP_KEY'),8);
if( isset($hashids->decode($value)[0]) )
{
$id = $hashids->decode($value)[0];
return App\Schedule::findOrFail($id);
}
App::abort(404);
});
And in the model:
public function getRouteKey()
{
$hashids = new \Hashids\Hashids(env('APP_KEY'),8);
return $hashids->encode($this->getKey());
}
Now this works fine the resource displays perfectly and the ID is hashed.
BUT when I go to my create route, it 404's - if I remove App::abort(404) the create route goes to the resource 'show' view without any data...
Here is the Create route:
Route::get('schedules/create', [
'uses' => 'SchedulesController#create',
'as' => 'schedules.create'
]);
The Show route:
Route::get('schedules/{schedule}', [
'uses' => 'Schedules Controller#show',
'as' => 'schedules.show'
]);
I am also binding the model to the route:
Route::model('schedule', 'App\Schedule');
Any ideas why my create view is not showing correctly? The index view displays fine.
Turns out to solve this, I had to rearrange my crud routes.
Create needed to come before the Show route...
There's a package that does exactly what you want to do: https://github.com/balping/laravel-hashslug
Also note, that it's not a good idea to use APP_KEY as salt because it can be exposed.
Using the above package all you need to do is add a trait and typehint in controller:
class Post extends Model {
use HasHashSlug;
}
// routes/web.php
Route::resource('/posts', 'PostController');
// app/Http/Controllers/PostController.php
public function show(Post $post){
return view('post.show', compact('post'));
}