2

I have a problem in my Laravel structure because I need to add many reports to my app, so I think it's not a good idea to put everything in the controller because my eloquent models allow me to list, add, insert and update, and my queries need more than one table with joins, and some math functions like sum(), max(), min().

When I used Codeigniter, I added methods with each query in the model file. So I can call it $sales->salesReport() and it gave me the data.

peterm
  • 91,357
  • 15
  • 148
  • 157
Developer933
  • 57
  • 1
  • 10

2 Answers2

3

The question is really a matter of what is being done and what is responsible. There are some excellent posts on where logic should be kept and what can be used. I am a little unclear as to whether you are asking about chaining something like scopes or more just where to put your logic. I would probably have a service:

<?php

class SalesReportService {

    public function generateReport(Sales $sales)
    {
        // logic here...

        return $result;
    }

}

and then in the controller it would be something like:

<?php

class SalesController extends Controller {

    public function __construct(SalesReportService $reportService)
    {
        $this->reportService = $reportService;
    }

    public function show(Sales $sales)
    {
        return $this->reportService->generateReport($sales);
    }

}
Community
  • 1
  • 1
Alex Harris
  • 6,172
  • 2
  • 32
  • 57
1

Laravel offers something similar to Codeigniter that matches what you described. It's called query scopes, or more precisely local scopes. You can keep them in your model and call them whenever you want.

You add in your model

public function scopeSalesReport($query) {
    return $query->join(...);
}

Source: https://laravel.com/docs/5.4/eloquent#local-scopes

EddyTheDove
  • 12,979
  • 2
  • 37
  • 45
  • Well, I think it's a good idea but if you have more tables you need more complex queries because it's a report, and I don't want to make a lot of joins with all the related tables. Can you tell me if it's possible to put a custom SQL query in a scope method? If so, it can work for me it could be a solution. Thanks. – Developer933 May 09 '17 at 04:06
  • What you put in a scope query is entirely up to you. You can join as many tables as you want. However, is it the best design approach ? Up to you to decide that. You can use Traits, Helpers, Services, Query Scope, etc. to accomplish the same thing. It ultimately depends on you. – EddyTheDove May 09 '17 at 04:35
  • So, is it correct to put these methods in a eloquent model? public function scopeSalesReport(){ return DB::select('select * from...'); } public function scopeSalesReportByMonth(){ return DB::select('select * from...'); } If not, is there another alternative? – Developer933 May 09 '17 at 06:03
  • When using query scopes, it's recommended to only put write functions that have something to do with that specific model. But if you want to just keep queries that will do some 'stuff' to you, you can use traits. In your controller you simple use that trait with `use App\Traits\Sales;` And every single function in that trait will be available to your controller. Laravel itself make a lot of use of traits. – EddyTheDove May 09 '17 at 07:13