Josh Mountain
Josh Mountain

Reputation: 1950

Calling a method within a view in Laravel 4

Let me preface this by saying I am brand new to Laravel and MVC in general. What I am trying to do seems simple but I'm not sure of the proper way to do it inside Laravel. I have a menu/sidebar view that looks like this:

@if( Auth::check() )

    <h4>Item Types</h4>
        <ul>
            {{ listUserTypes() }}
        </ul>
@endif

What I would like to do is get from MySQL any 'Types' that exists for the current user and loop through them as <li>s. I know putting login into the view is definitely the wrong way to do this, but I'm not sure of the correct alternative. Is is proper to put my DB query as a method listUserTypes() inside my controller, and if so how would I call that inside a view?

Upvotes: 0

Views: 135

Answers (4)

Javi Stolz
Javi Stolz

Reputation: 4755

As you are using MVC pattern the proper way should be define the relations in your models, get the data in your controller and make your view as 'dumb' as possible, that is, the view should only show data w/o knowing where or how the data is retrieved. Using a function in your view means your view is too 'smart'.

// =========== models/User.php ===========

public function types()
{
    return $this->hasMany('Type');
}

// =========== controllers/SomeController.php ===========

$user = Auth::user();

return View::make('some.view')->withTypes($user->types);

// =========== some/view.blade.php ===========

<ul>
    @foreach ($types as $type)
    <li>{{ $type->name }}</li>
    @endforeach
</ul>

Upvotes: 2

Needpoule
Needpoule

Reputation: 4576

I would put the DB query in a method inside your User model.

Then, you will be able to call this method like this:

Auth::user()->listUserTypes()

If you don't want to call a model directly in your view, an other option is to use the view composer function of Laravel.

http://laravel.com/docs/responses#view-composers

View::composer(array('menu.sidebar'), function($view)
{
  $view->with('userTypes', Auth::user()->listUserTypes());
});

With this, each time your menu.sidebar view is called, the userTypes variable will be provided.

This way you don't have to send the userTypes variable every time you render a view including menu.sidebar.

Upvotes: 0

Devatoria
Devatoria

Reputation: 685

I think you should have this function in your model (a "scope" function retrieving all types for a given user). Then, you call this function in your controller, store result (array) in a variable and pass it to your view. Then, you can use it easily.

Model/Type entity

public function scopeByUser($query, $user) {
    return $query->...; // Make your query to retrieve types using passed user.
}

Controller

$types = Type::byUser($user)->get();
return View::make('myview', array('types' => $types));

View

<ul>
    @foreach($types as $type)
        <li>{{ $type->label }}</li>
    @endforeach
</ul>

Where label is the value you want to display.

Upvotes: 1

Mike Stivala
Mike Stivala

Reputation: 111

Your views should be "dumb". Whenever you find yourself in the situation where a view requires data, code under the assumption that it already has access to it:

@foreach( $userTypes as $userType )
    <li>{{ $userType }}</li>
@endforeach

Then in the controller, pass the data to it:

return View::make('pages.homepage')
        ->with('userTypes', $userTypes);

Upvotes: 2

Related Questions