Breezer
Breezer

Reputation: 10490

Laravel Eloquent: belongsToMany collection get value

I have following relation

Tasks has many to many relation with Categories Categories has one to many relation with Types

I'm using this in my task controller currently to get all the data I want, which works almost as wanted:

$type = Type::with('categories.tasks')
        ->where('slug', $type)
        ->first();

This returns type, with a categories collection, each category has a tasks collection, and each tasks have a category collection. This structure is correct by design, problem is the category child collection to task returns all categories, but I want it to be limited to the same condition as the parent category collection which is where('slug', $type) and I want the collection return not to be an array since the result will always only return one category if condition is applied.

I've tried using scope but with no success. Any help would be much appreciated.

My table and respective models

Type Table

CREATE TABLE `types` (
      `id` int(11) NOT NULL,
      `slug` varchar(60) NOT NULL,
      `created_at` timestamp NOT NULL DEFAULT current_timestamp(),
      `updated_at` timestamp NOT NULL DEFAULT current_timestamp()
    ) 

Type Model

 class Type extends Model{
 public function categories()
    {
        return $this->morphMany(Category::class, 'categorize');
    }

    public function project()
    {
        return $this->belongsTo(Project::class);
    }
    }

Category Table

CREATE TABLE `categories` (
  `id` int(10) NOT NULL,
  `title` varchar(128) NOT NULL,
  `color` varchar(10) NOT NULL,
  `content` varchar(128) NOT NULL,
  `categorize_id` int(6) NOT NULL,
  `categorize_type` varchar(256) NOT NULL,
  `created_at` timestamp NOT NULL DEFAULT current_timestamp(),
  `updated_at` timestamp NOT NULL DEFAULT current_timestamp()
)

Category Model:

  class Category extends Model
  {
 public function categorize(){
        return $this->morphTo();
    }
    public function tasks(){
        return $this->belongsToMany(Task::class,'task_category');
    }
    public function types(){
        return $this->belongsTo(Type::class);
    }
    }

Tasks Table

CREATE TABLE `tasks` (
  `id` int(10) UNSIGNED NOT NULL,
  `project_id` int(11) NOT NULL,
  `title` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
  `desc` text COLLATE utf8mb4_unicode_ci NOT NULL,
  `is_completed` tinyint(1) NOT NULL DEFAULT 0,
  `start` timestamp NOT NULL DEFAULT current_timestamp(),
  `end` timestamp NULL DEFAULT NULL,
  `allDay` tinyint(1) NOT NULL DEFAULT 0,
  `created_at` timestamp NULL DEFAULT current_timestamp(),
  `updated_at` timestamp NULL DEFAULT current_timestamp(),
  `deleted_at` timestamp NULL DEFAULT NULL
) 

Pivot table

CREATE TABLE `task_category` (
  `task_id` int(11) NOT NULL,
  `category_id` int(11) NOT NULL
) 

Task Model

   class Task extends Model
{

 public function category(){
      return $this->belongsToMany(Category::class,'task_category','task_id','category_id');
    }
    }

Edit: I have rephrased my question and added all information about models and tables

Upvotes: 0

Views: 1239

Answers (1)

N69S
N69S

Reputation: 17216

When using the data from

$type = Type::with('categories.tasks')
        ->where('slug', $type)
        ->first();

if you get the category from the task like this

foreach($type->categories as $category) {
    foreach($category->tasks as $task) {
        $wantedCategory = $task->categories; //like this
    }
}

then yes, it will get you all the categories linked to that task,

what you need is just use the variable $category from your loop (or index)

we could help you more if you provide database structure and how you try to recover the category in question.

Upvotes: 1

Related Questions