1

i have the following Template model and TestCategory hasMany Test:

class Template extends Model
{
protected $table = 'test_templates';

protected $fillable = [
    'customers_id',
    'tests_categories_id',
    'tests_id'
];

public function customers(){
    return $this->belongsTo(Customer::class, 'customers_id');
}

public function testCategories(){
    return $this->belongsTo(TestCategory::class, 'tests_categories_id');
}

public function tests(){
    return $this->belongsTo(Test::class, 'tests_id');
}
}

And I have the following index method defined in TemplateController

public function index($customerId)
{
$templates = Template::with( 'customers','testCategories','tests')
                      ->where('customers_id', $customerId)->get();
$templates = $templates->groupBy('tests_categories_id');
$templates = json_decode($templates, true);
$templates = array_values($templates);
return response()->json(['Status' => True, 'template' => $templates]);
}

I got the following json output:

{
"Status": true,
"template": [
    [
        {
            "id": 1,
            "customers_id": 1,
            "tests_categories_id": 1,
            "tests_id": 1,
            "created_at": "2018-09-10 11:03:44",
            "updated_at": "2018-09-10 11:03:44",
            "customers": {
                "id": 1,
                "name": "Queen PVT.Ltd",
                "address": "gotham",
                "contact_number": "9842********",
                "created_at": "2018-09-10 11:03:43",
                "updated_at": "2018-09-10 11:03:43"
            },
            "test_categories": {
                "id": 1,
                "name": "General Tests",
                "created_at": null,
                "updated_at": null
            },
            "tests": {
                "id": 1,
                "tests_category_id": 1,
                "name": "Lamination",
                "created_at": null,
                "updated_at": null
            }
        },
        {
            "id": 2,
            "customers_id": 1,
            "tests_categories_id": 1,
            "tests_id": 2,
            "created_at": "2018-09-10 11:03:44",
            "updated_at": "2018-09-10 11:03:44",
            "customers": {
                "id": 1,
                "name": "Queen PVT.Ltd",
                "address": "gotham",
                "contact_number": "984*******",
                "created_at": "2018-09-10 11:03:43",
                "updated_at": "2018-09-10 11:03:43"
            },
            "test_categories": {
                "id": 1,
                "name": "General Tests",
                "created_at": null,
                "updated_at": null
            },
            "tests": {
                "id": 2,
                "tests_category_id": 1,
                "name": "Paper Type",
                "created_at": null,
                "updated_at": null
            }
        }
    ],
    [
        {
            "id": 7,
            "customers_id": 1,
            "tests_categories_id": 2,
            "tests_id": 8,
            "created_at": "2018-09-10 11:03:44",
            "updated_at": "2018-09-10 11:03:44",
            "customers": {
                "id": 1,
                "name": "Queen PVT.Ltd",
                "address": "gotham",
                "contact_number": "984******",
                "created_at": "2018-09-10 11:03:43",
                "updated_at": "2018-09-10 11:03:43"
            },
            "test_categories": {
                "id": 2,
                "name": "Scratch Test",
                "created_at": null,
                "updated_at": null
            },
            "tests": {
                "id": 8,
                "tests_category_id": 2,
                "name": "HRN Visibility",
                "created_at": null,
                "updated_at": null
            }
        }
    ]
]
}

I want to collect all the tests as per the test_categories without reprinting customers and test_categories as following:

{
"Status": true,
"template": [
    [
        {
            "id": 1,
            "customers_id": 1,
            "tests_categories_id": 1,
            "tests_id": 1,
            "created_at": "2018-09-10 11:03:44",
            "updated_at": "2018-09-10 11:03:44",
            "customers": {
                "id": 1,
                "name": "Queen PVT.Ltd",
                "address": "gotham",
                "contact_number": "984*****",
                "created_at": "2018-09-10 11:03:43",
                "updated_at": "2018-09-10 11:03:43"
            },
            "test_categories": {
                "id": 1,
                "name": "General Tests",
                "created_at": null,
                "updated_at": null
            },
            "tests": {
                {
                "id": 1,
                "tests_category_id": 1,
                "name": "Lamination",
                "created_at": null,
                "updated_at": null
                },
                {
                "id": 2,
                "tests_category_id": 1,
                "name": "Paper Type",
                "created_at": null,
                "updated_at": null
                }
            }
        }
    ],
    [
        {
            "id": 7,
            "customers_id": 1,
            "tests_categories_id": 2,
            "tests_id": 8,
            "created_at": "2018-09-10 11:03:44",
            "updated_at": "2018-09-10 11:03:44",
            "customers": {
                "id": 1,
                "name": "Queen PVT.Ltd",
                "address": "gotham",
                "contact_number": "984265*****",
                "created_at": "2018-09-10 11:03:43",
                "updated_at": "2018-09-10 11:03:43"
            },
            "test_categories": {
                "id": 2,
                "name": "Scratch Test",
                "created_at": null,
                "updated_at": null
            },
            "tests": {
                {
                "id": 8,
                "tests_category_id": 2,
                "name": "HRN Visibility",
                "created_at": null,
                "updated_at": null
                }
            }
        }
    ]
]
}
4
  • Your actual and expected outputs are the same, so I think you made a mistake there. If you fix that hopefully someone should be able help you. Commented Sep 20, 2018 at 18:26
  • tests attribute is different. I want to collect all the tests as per the test_categories Commented Sep 21, 2018 at 4:17
  • You really want someone to look at every minute detail, explain what's different Commented Sep 21, 2018 at 5:07
  • I want to get {Template : { customer : {}, test_category : { tests:{tests1, test2}}} but I am getting {Template1 : { customer : {}, test_category : { tests:{tests1}},Template2 : {customer : {}, test_category : { tests:{tests2}}} Commented Sep 21, 2018 at 10:17

1 Answer 1

1

If I understand the problem correctly the tests are being separated into different templates when you are expecting some of them to be related to the same template.

This is because your Template class is storing the test_id that it belongs to and it can only store 1 test per Template. So when you are calling Template::with('tests') it can only return one Test::class.

Because you expect to see that many Tests belongTo one Template, and when you look at the relationship from the Template to Test, you expect that a Template has many Tests. Therefore, your Template class should implement the hasMany relationship like so:

class Template extends Model
{

protected $fillable = [
    'customers_id',
    'tests_categories_id' // notice the removal of the test_id which should also be removed from the test_templates migration
];
    ...

    public function tests(){
        return $this->hasMany(Test::class); //change belongsTo to hasMany
    }

    ...
}

Instead of storing the test_id on the Template class you should be storing the template_id on your Test class and look something like so:

class Test extends Model
{

protected $fillable = [
    ...
    'test_template_id' // This should be added to $fillable and the tests migration
    ...
];
    ...

    public function template(){
        return $this->belongsTo(Template::class, test_template_id);
    }

    ...
}

Now when you call Template::with('tests') it can return many Test::class and should match your expected output.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.