Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Ligonsker's avatar

Should I get the model name from the input or from the URL?

I have list of URLs that display data tables that the user can update. Each of these tables has a matching model, however their names aren't always identical. For example:

tables/table1      // matches model TableOne
tables/table_two   // matches model Table2
tables/table_3     // matches model Table3

The users can update these tables so I want to have the same script but get the model name or table name dynamically.

Should I do it by sending the URL then have a file that translates the URL to the matching model/table names. Or, should I output the exact model/table name in the Blade file as a hidden input then submit it with the form?

Ty

0 likes
12 replies
Sinnbeck's avatar

You can perhaps make a look up map?

$map = [
    'table1' => TableOne::class,
    'table2' => TableTwo::class,
];
$model = app($map[$table]);
$model->query()->where('foo', 'bar')->get(); //etc
1 like
Ligonsker's avatar

@Sinnbeck Yes! didn't know about the map helper, thank you.

And if I need to use that in more than one controller, where do you suggest I put that map? Would you create a special folder for it, like Helpers in the root of the project or somewhere else?

Ligonsker's avatar

@Sinnbeck sorry, typo, I meant app helper

Nope, there are many tables and each controller can use all of them. Where do you think would be the best place to then put the mapping file?

(Most of the times though each controller has its own set of tables though, but sometimes another controller can access this table)

Sinnbeck's avatar
Sinnbeck
Best Answer
Level 102

@Ligonsker Ok. Well at least this will help ensuring that you only allow certain tables. But are the colums the same on all or ?

The app() helper https://laravel.com/docs/9.x/helpers#method-app

And yes you can perhaps make a helper class for looking up the correct model.

ModelFinder::find($table);

and the class

class ModelFinder
{
    public static function find($table)
    {
        $map = [
            'table1' => TableOne::class,
            'table2' => TableTwo::class,
        ];
        if (!isset($map[$table]) {
           throw new \Exception('Invalid table!');
         }
         return app($map[$table]);
    }
}
1 like
Ligonsker's avatar

@Sinnbeck thanks, will use this class! Would you suggest taking the table name from the URL or as hidden input in the Blade file?

Also, the columns are not the same on all, there are some repeating columns but then the data itself is different for each table - why? Do you have suggestion for case the columns are/are not identical?

And for good practice with Laravel - where would you suggest placing the ModelFinder class?

Sinnbeck's avatar

@Ligonsker I would probably use a hidden field. Dont really have any tips for how to work with whatever fields comes in as I have never needed to build something like this (I would have a route for each table).

Put the class wherever it makes sense to you. Maybe something like /app/Support

1 like
Ligonsker's avatar

@Sinnbeck Yes! There is route for each table right now - each table has route for the get and the update.

What I want to do is to merge at least the update part since for the update only certain and identical columns are allowed to be updated.

I am trying to make it more reusable so that if a change is needed, I don't have to go to each table's update route and edit it there.

Is it a good idea? OR I should leave the update routes separate as well?

(Just to make it clear: the tables have different data columns, but most of the tables have the same columns of update in this case, some specific columns for certain confirmation by the user)

In this case - should I merge all the updates to one and leave the get separate, or have both update and get separate for each table?

Because right now I have to change something in the update code and it means if I don't merge the update code I have to do it for each separate update route. But since the update route code is identical I might just make it into one

Sinnbeck's avatar

@Ligonsker I would personally leave it split up myself. While it might seem that they are similar, I can tell they arent 100%. This will make the code harder to test, and there will be a big chance that a small change can break several table updates.

1 like
Ligonsker's avatar

@Sinnbeck You are correct and since they did seem similar, I went on each of the update's code to check and wrote the identical and different updates down.

I noticed that 80% of the updates are exactly the same - only the model name is different - hence why I made this post about mapping between the input to the model name.

For the 20% others - I would leave separately.

Why? Because right now I need to do a relatively simple change - to add another identical input column to all the tables, which is hundreds. So it means I have to go to each table's blade and add this column, then go to each update function in the controller and update the code there, so it's hundreds times two actions to do

I thought that if I might be able to reduce it by about 80% and have much less to update.

Or, you have better suggestion in such case?

kokoshneta's avatar

@Ligonsker I would definitely keep it to just one Blade template, rather than hundreds of near-identical ones; and probably one controller as well, as far as possible.

I would have all the table models extend a base model (or use a base trait) which has a method that returns a list of columns to update for the 80%. In the table models that don’t just use the exact same columns (the 20%), override the parent/trait function to return the column needed for those specific models.

Then, in your Blade template, you use the return value of that method in your template to define which input fields are shown.

Even better, create a class that represents an update column for a table, with properties for all the things you need to show it on the page (input type, placeholder text, default value, etc.), and make sure the parent/trait method returns an array of objects of that class. Then make a Blade component that expects an array of objects of that class and uses it to generate the input fields to display, and include that component in whatever Blade templates you have for update pages.

1 like
Ligonsker's avatar

@kokoshneta thank you for this, I am starting to work on it already and see if it really doesn't break anything hopefully as @sinnbeck warned correctly, and hopefully it will work well.

I mean, 80% are literally copy-paste of the same method just different name.

Please or to participate in this conversation.