Open HichemBenali opened 2 years ago
Hi @HichemBenali, as with any religious dispute, there is no one right answer. There are two approaches to this issue: thick controllers and thin models, and vice versa. In the first case, as you might guess, the business logic is located in the controllers, in the second - in the models.
In screens - there was a point, in that you can tell exactly what is happening on it simply by going to this class, where the data comes from, what actions exist, etc. which reduces the cognitive load on understanding what is happening.
I can offer you some good solutions in my opinion for building an application:
Actions
Creation of ordinary classes that perform only one simple "Action" method and can be called from various variations (Controllers, services, console). For example:
namespace App\Actions;
class CreateOrder
{
/**
* Generate new order for the user.
*
* @param mixed $user
* @return void
*/
public function __invoke($user)
{
// Your code
}
}
Then call it on the screen:
(new CreateOrder)($user)
Real examples in Laravel application can be seen here: https://github.com/laravel/fortify/tree/1.x/src/Actions There are also various packages that elevate this way of working to the absolute: https://laravelactions.com/ Also read https://stitcher.io/blog/laravel-beyond-crud-03-actions
Services
You can also create a completely new file, in which you would combine actions that can be performed on a certain semantic logic.
namespace App\Actions;
class Shop
{
public function createOrder($user)
{
// Your code
}
}
This is a slightly more complex option, because it combines a larger area of responsibility.
Model
If the application is small and was not going to be ambitious, then it is very common to see business logic in regular Eloquent models:
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Order extends Model
{
public static function createNewOrder($user)
{
// Your code
}
}
That is, there are a lot of accommodation options and they are different. You can choose according to your taste, in order not to duplicate the code, for example, in the admin panel and the client part of your web application.
Services
Placing directly in the controller makes sense when your code is never needed again in another part of the application. In all other options, it is better to take it out of the controller.
If your code is exclusively distributed to screens and there is no more use for it. Then consider the inheritance option:
namespace App\Http\Controllers\Screens;
class OrderList extends Order
{
//...
}
Where the order creation method would be defined in the main screen:
namespace App\Http\Controllers\Screens;
use Orchid\Screen\Screen;
class Order extends Screen
{
//...
public function createNewOrder()
{
// Your code
}
}
Then the method will be available for calling on both pages.
As I said earlier, there is no unambiguously right or wrong option that I could advise you, but I tried to tell you a few options from which you can choose your own that will suit your project. You can learn more about the architecture of the application yourself, as it is beyond the scope of a simple comment.
As for the subject itself, you can specify any point to send the form from the screen:
Button::make('Go')->action('https://example.com')
To which the POST request will be made
Problem is: I prefer to keep the business logic in the screens (Or controllers) which causes a lot of duplicate code for the same function.
Describe the solution you'd like Allowing the usage of methods from other screens. Something similar to how laravel's routing works.
Describe alternatives you've considered I have considered using separate classes for the logic but i always end up with duplicate code specially when there is the same functionality in multiple forms. eg: Can create an order from a specific page, or from a quick modal.