Laravel 5 call a model function in a blade view
Asked Answered
D

8

36

I want to build a blade view from 3 tables:

  • "inputs_details" - fields: article_type (values: 'p' for product,'s' for service), article_id, ....
  • "products" - fields: id, name
  • "services" - fields: id, name

enter image description here

But, in browser, I have the error: "Class 'Product' not found".

Is there a solution to pass to the view this function (to find the name of the product or the service based on article_type and article_id)?

I was trying also with join query, but I couldn't put so many conditions in a single join query .. where article_type is "p", then join with "products" table ... or .... where article_type is "s", then join with "services" table.

Downer answered 12/3, 2015 at 10:46 Comment(2)
You are bypassing the C (controller) part in MVC pattern (Laravel is a MVC framework). You should not do that. Instead invoke the model from the controller and expose whatever data you fetched from it in a template variable which then can be used in the Blade view.Zo
Why are you using this concept ? It means you are insulting the laravel framework. It's not the way you are doing it. You are eating the MVC concepts of laravel. LolxFlick
C
82

Related to the question in your answer:

You have multiple options to achieve this that are way better:

Let's assume you have a model which you pass to the view:

$model = Model::find(1);
View::make('view')->withModel($model);

Now in your Model you could have a function:

public function someFunction() {
    // do something
}

In your view you could call that function directly:

{{$model->someFunction()}}

This is nice if you want to do something with the model (the dataset).

If not you can still make a static function in the model:

public static function someStaticFunction($var1, $var2) {
    // do something
}

And then:

{{App\Model::someStaticFunction($yourVar1,$yourVar2)}}

Hope it helps.

Cryometer answered 12/3, 2015 at 14:6 Comment(11)
But, if I want to pass a static function from a Controller to view, what is the syntax?Downer
Why would you do that? As said you just can make a static function in your model and call it in the view. You don't have to pass anything then.Cryometer
@Robert what exactly do you mean?Cryometer
@Cryometer - thanks for quick repsonse :) I'm wondering if passing model to view and in general accessing model directly in blade view is good practice. I'm wondering because I'm working on my custom ACL without usage of Gates and I'm wondering how should I approach access rights in views in this case.Carton
@Carton yes of course! You are surely doing it already. If you need to display the username for example you'll be doing something like {{$user->username}}. The $user is your User-Model.Cryometer
@Cryometer Ok thank good to know. Right now I have something like this: In Controller I user service taht I've created and I'm passing result of this service to the view. That's why I was concerned because I've always avoided passing object. I always pass just data I want to access in view. And what do you think about writing custom helper and than use it in view?Carton
@Robert: Since it's getting a bit off-topic here, how about joining the laravel-chatroom on stackoverflow?Cryometer
@Cryometer sure thing. I will visit you guys today.Carton
Nice code but the first block (with $model) should be put in a controller method together with the View::make() invocation, else you break the MVC pattern.Zo
@Zo of course it should. I didn't think I had to say so.Cryometer
The question starter invoked a model method directly in his view, so I thought might be worth mentioning it.Zo
D
15

I solve the problem. So simple. Syntax error.

  • App\Product
  • App\Service

enter image description here

But I also want to know how to pass a function with parameters to view....

Downer answered 12/3, 2015 at 12:4 Comment(3)
Can you explain that: "... how to pass a function with parameters to view..."?Cryometer
@Cryometer I want to pass a private function from controller to view with parameters like this: return view('admin.inputs.create')->with(function($parameter1,@parameter2)); in view I want to use that function to return variables based on parameters from view.Downer
Why don't you pass an object and call the function on it? Or you could make a static function collection which you can call whenever you want.Cryometer
L
15

want to use model in view as:

{{ Product::find($id) }}

you can use in view:

<?php
$tmp = \App\Product::find($id);
?>
{{ $tmp->name }}

Hope this will help you

Lamp answered 19/1, 2019 at 9:0 Comment(0)
T
10

In new version of Laravel you can use "Service Injection".

https://laravel.com/docs/5.8/blade#service-injection

/resources/views/main.blade.php

@inject('project', 'App\Project')

<h1>{{ $project->get_title() }}</h1>
Tartan answered 26/8, 2019 at 13:21 Comment(0)
M
2

Instead of passing functions or querying it on the controller, I think what you need is relationships on models since these are related tables on your database.

If based on your structure, input_details and products are related you should put relationship definition on your models like this:

public class InputDetail(){
 protected $table = "input_details";
 ....//other code

 public function product(){
   return $this->hasOne('App\Product');
 }
}

then in your view you'll just have to say:

<p>{{ $input_details->product->name }}</p>

More simpler that way. It is also the best practice that controllers should only do business logic for the current resource. For more info on how to do this just go to the docs: https://laravel.com/docs/5.0/eloquent#relationships

Mezcaline answered 28/3, 2016 at 2:57 Comment(0)
P
2

I ran into a similar issue where I wanted to call a function defined in my controller from my view. Although it perplexed me for a while trying to figure out how to get to the controller from the view it turned out to be fairly straightforward.

I hand off an array to my views with data records that the view formats and presents to the user with jQuery DataTables (big duh). One column in the presented UI table is a set of action buttons that need to be created per row based on the content of the data in each of the rows. I guess I could have added the button definitions to the data rows as a column sent to the views but not all views needed the buttons so why? Instead, I wanted the view that needed them add them.

In the controller I pass a reference to the controller itself to the view as in

->with('callbackController', $this)

I called it callbackController as that is what I was doing. Now, inside my view I can either escape to PHP to use $callbackController to access the parent controller as in

<?php echo $callbackController->makeButtons($parameters); ?>

or just use the Blade mechanism

{!! $callbackController->makeButtons($parameters); ?>

It seems to be working fine across multiple controllers and views. I have not noticed a performance penalty using this mechanism and I have one huge table with over 50K rows.

I have not tried to pass on references to other objects (e.g., models, etc) yet but I do not see what that would not work as well

Might not be elegant but it seems to get the job done.

Presentative answered 28/2, 2017 at 17:14 Comment(1)
Passing a reference to the current controller seems like bad practice. I would suggest something like the repository pattern or create a library of reusable functions. You controller and anywhere else is your project can use those functions.Hawkeyed
I
0

You can pass it to view but first query it in controller, and then after that add this :

return view('yourview', COMPACT('variabelnametobepassedtoview'));
Inert answered 26/3, 2016 at 6:56 Comment(0)
U
0

Imagine that your model name is 'company' and you want to retrieve name of company based on ID: in model:

class company extends Model
{     
    public static function showCompanyName($id_fetched){
        $companyName=company::query()
        ->where('id',$id_fetched)->first()->company_name;
        return $companyName;
    }
}

In your blade:

<?php
use App\Models\company;

?>

@dd(company::showCompanyName(5))

You can send every number instead of 5 as argument of showCompanyName

Best

Unglue answered 8/12, 2023 at 9:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.