Closed Saneesh closed 4 years ago
Hi Saneesh,
The reason you’re getting the exception is due to changes in the Laravel framework. We wrote the book when the current version of Laravel was 5.8 and in-between one of the later releases of Laravel 6 and Laravel 7, the way Laravel handles route parameters was changed.
Now you have to give the exact name of the route parameter and are not able to use the id
key anymore, when using the route()
helper function.
To fix this, you should make the following change in the BookResource class:
class BookResource extends JsonResource {
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request) {
return [
'id' => (string) $this->id,
'type' => 'books',
'attributes' => [
'title' => $this->title,
'description' => $this->description,
'publication_year' => $this->publication_year,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
],
'relationships' => [
'authors' => [
'links' => [
'self' => route('books.relationships.authors', [
'book' => $this->id,
]),
'related' => route('books.authors', [
'book' => $this->id,
]),
],
'data' => $this->authors->map(function ($author) {
return [
'id' => $author->id,
'type' => 'authors',
];
}),
],
],
];
}
}
Notice how the id
key in the route()
helper function has been changed to book
.
The same has to be done in the test:
/**
* @test
*/
public function it_returns_a_relationship_to_authors_adhering_to_json_api_specification() {
$this->withoutExceptionHandling();
$book = factory(Book::class)->create();
$authors = factory(Author::class, 3)->create();
$book->authors()->sync($authors->only('id'));
$user = factory(User::class)->create();
Passport::actingAs($user);
$this->getJson('/api/v1/books/1', [
'accept' => 'application/vnd.api+json',
'content-type' => 'application/vnd.api+json',
])
->assertStatus(200)
->assertJson([
'data' => [
'id' => '1',
'type' => 'books',
'relationships' => [
'authors' => [
'links' => [
'self' => route('books.relationships.authors', [
'book' => $book->id,
]),
'related' => route('books.authors', [
'book' => $book->id,
]),
],
'data' => [
[
'id' => $authors->get(0)->id,
'type' => 'authors',
],
[
'id' => $authors->get(1)->id,
'type' => 'authors',
],
],
],
],
],
]);
}
We are in the midst of updating the book to Laravel 7 and will be releasing the updated version as soon as possible.
@ThomasNoergaard First of all you guys are superb! :-)
Your solution is working! and my quick fix was for all route():
'self' => route('books.relationships.authors', [$book->id]),
Typo in the book:
You might be already noticed, many test case function names contain an_book
it should be a_book
.
Thank you very much, we're glad we could help.
Thank you, we will note that and correct it in the updated version :-)
I'm getting the following error when I test the relationships:
Illuminate\Routing\Exceptions\UrlGenerationException Missing required parameters for [Route: books.relationships.authors] [URI: api/v1/books/{book}/relationships/authors].
Detailed questing is asked below link: https://laracasts.com/discuss/channels/testing/illuminateroutingexceptionsurlgenerationexception-missing-required-parameters-for-route-booksrelationshipsauthors-uri-apiv1booksbookrelationshipsauthors
Laravel : 7.14.1
Regards, Saneesh