What's the best way to handle repetitive code across controllers?
So, consider a file repository. It has a File model, which has many Versions of that file, and each one of those has one or more Link objects that reference a URL. When I build the workflow for the file uploader, I started with the full File creation, which also takes the Version information and the Link to reference, and saves them all in one request to FileController@create. Then I started building more targeted administration screens, like adding a new Version. That also involves providing a Link and both the Version and Link are created in one request to VersionController@create. Now I'm making a form just to add additional links and, go figure, I've got the exact same code fragment I used in FileController and VersionController now in LinkController to handle the downloading of the file from the remote server.
What would be the suggested way to split this off into its own function? It will always take a Request $request and always look for the same fields. In fact, I should probably be separating the form sections into their own smaller Blade templates and yield them.
@bluesoul I’m not sure what repetition you have as it seems you have the entities pretty well modelled.
I tend to create resource controllers around my entities. If the File model is the “root” and you have child models from that, then you can use route–model binding when adding related models.
If a File has many Version records, then you could have a FileVersionController that looks like this:
class FileVersionController extends Controller
{
public function store(CreateVersionRequest $request, File $file)
{
$file->versions()->create($request->all());
// Redirect
}
}
If you can show us some code where you’re repeating yourself, then we can maybe suggest more specific solutions.
Not sure if this is the best way but it works for me.
You could use a helpers file by creating a file named helpers.php in the Http directory and put the code in a function there then add the following line to autoload in your composer.json file:
A few options. Create a helper function that you can then call globally. Another is to create a trait, and then use the trait on classes where you need the added function. Another option is to create a base controller, that extends the regular controller and put your additional methods in there, and then have your other controllers that need that functionality extend your new base controller.
What I ended up doing was adding a new method in LinkController called public function saveLink(Request $request, $type) that can tell where the request is originating from and inject the proper data and then handle the business of storing the data.
Now in the FileController::create() method I just call:
$saveLink = new LinkController;
$saveLink->saveLink($request, "File");
This is me still getting a handle on OOP, and understanding how classes and methods can interact with each other. Thanks for the input, everyone.