sj's avatar
Level 3

How to handle multidimensional arrays

Hey all,

I working on a side project where I'm starting with TDD and have a test data set like this

    /** @test */
    public function it_can_create_diet_plans() {
        $user = factory(User::class)->create();

        $data = [
            'diet_plan' => [
                'id'          => 1,
                'user_id'     => $user->id,
                'active'      => true,
                'title'       => 'Kost program til Simon',
                'description' => 'Kost program til Simon Jensen',

                'diet_days' => [
                    'id'      => 1,
                    'diet_id' => 1,
                    'weekday' => 'Mandag',

                    'diet_meals' => [
                        'id'          => 1,
                        'diet_day_id' => 1,
                        'meal'        => 'Morgenmad',

                        'diet_items' => [
                            'id'           => 1,
                            'diet_meal_id' => 1,
                            'grams'        => '20',
                            'protein'      => '22',
                            'carb'         => '400',
                            'fat'          => '20',
                        ],
                    ],
                ],
            ],
        ];

        $create_diet = $this->actingAs($user)->post(route('diet.store'), $data);

        dd($create_diet);
    }

and right now I have this on my controller

    public function store(Request $request)
    {
        $request = $request->all();
        $diet_plan = $request['diet_plan'];
        $diet_days = $request['diet_plan']['diet_days'];
        $diet_meals = $request['diet_plan']['diet_days']['diet_meals'];
        $diet_items = $request['diet_plan']['diet_days']['diet_meals']['diet_items'];
    }

I like that this way and i think there must be a better way to handle that.

0 likes
6 replies
D9705996's avatar

To be honest I think you need to look at your application structure as your doing way too much in one place. I would split out your routes to something like

/diet/plan
/diet/plan/{plan}/days
/diet/plan/{plan}/days/{day}meals
...

This will allow you to incrementally build up your data using factories and will really simplify you tests e.g.

  • given I have a diet day
  • and I post to `diet/plan/{plan}/days/{day}meals
  • i should have ond record in meals table ...
wing5wong's avatar

you can access array data with dot notation if you just want a cleaner look - https://laravel.com/docs/5.7/requests#retrieving-input

$diet_plan= $request->input('diet_plan');
$diet_days= $request->input('diet_plan.diet_days');
$diet_meals = $request->input('diet_plan.diet_days.dietmeals');
$diet_items= $request->input('diet_plan.diet_days.dietmeals.diet_items');
sj's avatar
Level 3

@D9705996 - Thanks for your reply.

Right now it's a one page with Vue where the user just click on a plus button to add days. meals etc.

What you mean is that the user should go to a new page to create days and a new page to create meals, right? or i misunderstand you?

D9705996's avatar

Yes I would create specific pages or components for each resource. If your already using Vue it shouldn't be to difficult to take you existing form and extract to components

https://vuejs.org/v2/guide/components.html

I generally find that if I start nesting data that I'm doing too much in the one route/action and should think about extracting to its own route/action.

sj's avatar
Level 3

@D9705996 - And then you would have more methods on my DietController like saveDay, saveMeals etc. :) ?

D9705996's avatar

You could add more methods however after watch Adam Wathan laracon 2017 presentation restful controllers I stick to the standard names e.g. index, store, destroy, etc and create more controllers

Strongly recommend watching the video and viewing the git repo. You code end up much more structured and forces you to extract complexity

https://murze.be/cruddy-by-design

Please or to participate in this conversation.