0

I have a practice Laravel app that displays training courses. To make it easier to use, I want to use categories, so if you want to see Cooking courses you can hit '/categories/cooking' and see all the cooking courses.

So I have my models and tables and relations set up. If I run:

return Category::with('courses')->where('slug','=',$slug)->firstOrFail();

I get:

[
    {
        "id": 1,
        "title": "Course 5",
        "description": "Ipsa ad quae optio dolorum et nesciunt nulla. Libero illum a quam provident alias sapiente. Omnis debitis quasi eius nihil enim. Ut saepe explicabo hic est rerum molestiae est. Iusto voluptatem aut non voluptatem qui fuga inventore. Et sit blanditiis amet fugit doloremque.",
        "cost": 1209,
        "slug": "autem-aspernatur-rerum-cumque-commodi-est-et",
        "category_id": 5,
        "created_at": "2020-06-16T13:09:56.000000Z",
        "updated_at": "2020-06-16T13:09:56.000000Z",
        "short_description": "Quod odit nam quisquam ab sint.",
        "length": 1,
        "pivot": {
            "category_id": 2,
            "course_id": 1
        }
    },
    {
        "id": 2,
        "title": "Course 3",
        "description": "Veniam voluptates velit veniam eum distinctio eum praesentium sed. Ad molestiae ea voluptatem aut velit ab. Voluptatum non ut facilis autem ducimus excepturi. Sit eum aperiam aut eos.",
        "cost": 1077,
        "slug": "iusto-doloremque-repellat-repellat-illo-rerum-libero",
        "category_id": 5,
        "created_at": "2020-06-16T13:09:56.000000Z",
        "updated_at": "2020-06-16T13:09:56.000000Z",
        "short_description": "Sint dolores omnis aut repudiandae quis.",
        "length": 1,
        "pivot": {
            "category_id": 2,
            "course_id": 2
        }
    }
]

Now, obviously I don't want all that for my view where a user is just picking a course. I only need the title, and the slug. So I made a Resource to filter everything:

public function toArray($request)
    {
        return [
            'id' => $this->id,
            'course_title' => $this->courses->title,
            'course_slug' => $this->courses->slug
        ];
    }

and in the controller:

return new CategoryShowResource(Category::with('courses')->where('slug','=',$slug)->get());

But this throws an exception:

"message": "Property [id] does not exist on this collection instance.",

Then it occurred to me that the Courses are inside an array. So if I do:

 $category = Category::with('courses')->where('slug','=',$slug)->firstOrFail();
 return $category->courses[0]->title;

Sure enough I just get

Course 5

The question is, how do use a Resource to filter what I want given that it doesn't seem to want to play nicely with the Courses array?

ElendilTheTall
  • 1,344
  • 15
  • 23

3 Answers3

0

try to get category first and then pass courses to collection function

$category = Category::with('courses')->where('slug','=',$slug)->get();
return CategoryShowResource::collection($category->courses);
Mohamed Sakr
  • 1
  • 1
  • 1
  • Same error: 'courses does not exist on this collection instance' – ElendilTheTall Jun 17 '20 at 21:23
  • ```dd($category->coureses);``` if it return array of courses you can return course data without using $this->courses->course_title instead use --> 'course_title' => $this->title, – Mohamed Sakr Jun 18 '20 at 10:58
  • that gives me the title of the category. I want the category title, and then the titles of all the courses associated with that category. – ElendilTheTall Jun 20 '20 at 20:24
0

Why don't you just make the select more selective. If you're using with( ), you could do it with something like

return Category::with('courses'=>function($query){
    $query->select('id','title', 'slug');
  })
)->where('slug','=',$slug)->firstOrFail();

Or for L5.5

return Category::with('courses:id, title, slug')->where('slug','=',$slug)->firstOrFail();

Check similar post

4givN
  • 2,936
  • 2
  • 22
  • 51
  • ````lluminate/Database/QueryException with message 'SQLSTATE[23000]: Integrity constraint violation: 1052 Column 'id' in field list is ambiguous```` – ElendilTheTall Jun 17 '20 at 21:26
  • what if you give another alias to `courses.id`? instead of `$query->select('id','title', 'slug');` you can do `$query->select(DB::raw(id as course_id, title, slug);` ? – 4givN Jun 17 '20 at 21:35
0

Found the answer to this. The solution is to use something like

'courses' => $this->courses->map->only('title','slug')
ElendilTheTall
  • 1,344
  • 15
  • 23