1

I want to set up a route that fetches all Contacts associated with a Customer. The endpoint would look like /customers/{customer}/contacts such that {customer} provides context for which contacts should be returned. My routes/web.php looks like this:

Route::get('/customers/{customer}/contacts', 'CustomerContactsController@index');

I generated the controller with --model=Contact specified. As a result, several of the methods come with type hinting out of the box, but the index() method doesn't, and actually won't run at all with any parameters supplied.

From CustomerContactsController.php:

public function index(Customer $customer)
{
    $this->authorize('update', $customer->account);

    $contacts = $customer->contacts;

    return view('contacts.index', compact('customer', 'contacts'));
}

This returns a completely blank screen. The associated Blade view looks like this:

@section('title')
{{ $customer->name }}
@endsection

@section('action')
    <a href="{{ $customer->path() . '/contacts/create' }}" class="button" >{{ __('Add New Contact') }}</a>
@endsection

@section('content')
<ul>
    @foreach ($contacts as $contact)   
        <li>{{ $contact->name }}</li> 
    @endforeach
</ul>
@endsection

I can still access the customer id inside the controller logic using Route::current()->parameters['customer'], but isn't there a better/easier way to do this?

Erich
  • 2,408
  • 18
  • 40
  • 1
    Can you share your code at `CustomerContactsController@index` – Elie Morin Jun 07 '19 at 04:40
  • 1
    ARGH! and here I was thinking something was wrong in the controller! In supplying the view code, I realized that `contacts/index.blade.php` view was missing the `@extends ('layout')` :( :( – Erich Jun 07 '19 at 05:07
  • did you try to `dd($contacts)`. actually, just check you getting data or not? – Karan Sadana Jun 07 '19 at 05:57

2 Answers2

1

Providing the {customer} parameter to the controller's index() method was the right way to go. After posting this question, I stumbled across the term nested resource controller which exactly described what I wanted to accomplish. In the help message for the php artisan make:controller command, I found the -p flag would do this for me.

I created a new controller using php artisan make:controller --model=Contact --parent=Customer TestCustomerContactsController and found that the only changes from my current controller were the exact changes I was already making to my existing controller.

The built-in debugging screen in Laravel was a red herring. Without having $customer scoped to the method, Laravel would kick back an error (as it should). With the variable properly scoped, the error message went away, but with a completely blank canvas it felt like I was going in the wrong direction entirely.

The fix

My view was full of @sections but without an @extends telling it which layout template to render to. Without providing this directive, any code within @section blocks doesn't get rendered, which in my case was the entire view, returning an empty page.

Answering the other question

In case it wasn't clear from @Developer's answer, any {parameter} present in the Route URI is also available via request()->parameter in the controller. E.g.

// routes/web.php
Route::get('/customers/{customer}/contacts/{contact}', 'CustomerContactsController@show');

// CustomerContactsController.php
public method show()
{
    $customer_id = request()->customer;
    $contact_id = request()->contact;
}
Erich
  • 2,408
  • 18
  • 40
0

If you getting value from in controller try this

your route is

Route::get('/customers/{customer}/contacts', 'CouponsController@testing');

and

try this in your controller

public function testing(Request $req)
{
    dd($req->customer);
}
Developer
  • 466
  • 7
  • 18
  • didn't think of that! although it wasn't my problem, that's good to keep in mind for the future. thanks! – Erich Jun 07 '19 at 05:10
  • hi @erich if you are using one more and go to function and ' , and use moled like create object and get value in function try this – Developer Jun 08 '19 at 04:36