DEV Community

Gustavo Jordan
Gustavo Jordan

Posted on

Someone could help me about calculations in blade views?

Hi, could someone suggest me the best way to work with a model, lest say a grades model that I pass to my blade view, and as I go throug it with a foreach I need to do some calculations, like to sum the grades of a specific subject and after all calc the median using the count of the collection pased, should I use the @php tag to specify a local variable in the view to sum the grades and make the calc or is there a better solution that you could suggest me?

This is what I did and it's working as I need but I want to improve it...

Here is the section of my controler

$subjects = Subject::all();
$subjectslevel = DB::table('subjects_periods_levels')->select('*')->where('lev_id', $levels->idlevel)->orderBy('subj_id')->get()->unique('subj_id');
$notasmostrar = Notasfinales::whereYear('ano', $fecha->year)->where('idstudent', $user->idnumber)->orderBy('idsubject')->get();
//dd ($notasmostrar);
$titulo = "Notas del Estudiante";
$profesors = User::where('activo',1)->get();
return view('grades.showgrades',['titulo' => $titulo, 'stud' => $user,'periodos' => $periodos, 'notas' => $notasmostrar, 'subjectslevel' => $subjectslevel, 'subjects' => $subjects, 'profesors' => $profesors]);
Enter fullscreen mode Exit fullscreen mode

here is the relevant part of my view

<tbody>
                    @foreach($subjectslevel as $levelsubjects)
                        <tr>
                                @php ($notafinal = 0)
                                <td>{{$levelsubjects->subj_id}}</td>
                                @foreach ($subjects as $subject)
                                    @if ($subject->id == $levelsubjects->subj_id)
                                        <td>{{$subject->name}}</td>


                                    @endif
                                @endforeach
                                @foreach ($periodos as $periodo)
                                    @foreach ($notas as $nota)
                                        @if ($periodo->idperiod == $nota->idperiodo)
                                            @if ($nota->idsubject == $levelsubjects->subj_id)
                                                <td>{{$nota->nota}}</td>
                                                @php ($notafinal = $notafinal + $nota->nota)
                                            @endif
                                        @endif
                                    @endforeach

                                @endforeach



                                    @foreach ($subjects as $subject)
                                        @if ($subject->id == $levelsubjects->subj_id)
                                            @foreach ($profesors as $profesor)
                                                @if ($profesor->idnumber == $levelsubjects->profe_id)
                                                    <td>{{$profesor->name}} {{$profesor->surname}}</td>
                                                @endif
                                            @endforeach
                                        @endif
                                    @endforeach
                                <td>
                                @php ($notafinal = $notafinal / $periodos->count())
                                {{$notafinal}} / 100</td>
                                <td><button type="button" class="btn btn-primary">Detalles</button></td>
                        </tr>
                    @endforeach
                </tbody>
Enter fullscreen mode Exit fullscreen mode

Top comments (8)

Collapse
 
alchermd profile image
John Alcher

I suggest you make your views as dumb as possible. What I mean by that is to do all calculations on the controller and only pass the finished data to the view. Ideally, your views contain as little logic as possible and should only concern themselves with presenting the data to the browser. Something like this should illustrate my point:

// Strive to make views as simple as this.
@foreach ($grades as $grade)
    {{ $grade }}
@endforeach

// And do all the heavy lifting in the controller
public function index()
{
    $grades = Grade::someQuery()->all();
    $computed = $grades->map(function ($grade) { /** do your work here */ });

    return view('grades.index', ['grades' => $computed]);
}

If you'd like to share some code, we'd be happy to help some more!

Collapse
 
gustavojordanra profile image
Gustavo Jordan

Thanks I added the code to the post.

Collapse
 
chrisrhymes profile image
C.S. Rhymes

There might be a collection method you could use on your models to make it easier for you. You could try chaining them, such as where and sum.

$grades->where(‘subject’, ‘history’)->sum(‘score’)

Laravel collections

Collapse
 
gustavojordanra profile image
Gustavo Jordan

I already think in that but it will only return the grades for the history subject acumulated, so how I pass all the results to the view, I need to pass all the subjects, like this but I need to group the results by subject and then pass to the view

Collapse
 
sebastiangperez profile image
Sebastiangperez

Always do calculations in your controller, the view only shows data.

Collapse
 
gustavojordanra profile image
Gustavo Jordan

Thanks, I already now that, but, how you suggest to do this then if I had a model with the grades but I need to show the calc and pass them to the view, should you suggest to use an array to store the calculations and pass that array to the view them? how you will do it?

Collapse
 
sebastiangperez profile image
Sebastiangperez

Do you have the code so we can see it? when i say "we", i mean this site.

Thread Thread
 
gustavojordanra profile image
Gustavo Jordan

yep I already add it to the post