ptvty
ptvty

Reputation: 5664

PHP - Use database in MVC view layer (Laravel Blade)

Is it generally a good idea to interact with database in view layer in MVC frameworks?

If I should, how can I connect to database from inc/header.php in right way?

I don't want make multiple connections one here at header.php and one in my pages controllers.

I'm more familiar with PDO than Laravel's database methods and ORMs.

Any advice is appreciated!

Edit

Friends gave nice advice and answers about MVC and Laravel workflow, but my main concern is still here.

Ok I have used controllers and models to get required data, then as I said, it should be present for the view layer in every page, So should I repeat the same task to get the same data in All my controllers' actions? (I guess that's why we have Filters here! then again, is it ok to use db in Laravel filters? using a model?)

Thanks in advance :)

Upvotes: 1

Views: 4135

Answers (4)

Ken Gee
Ken Gee

Reputation: 11

The answer and issue here is not so simple. First have just been introduced to MVC and trying to understand the basic concept, the flow for MVC is Controller->Model->View. Here we see that the data is passed from the model directly to the View. The current examples of how to use Laravel MVC is to have the Model return data to controller making the flow as follows: Conntroller->Model-Controller->View. Here we see that the model and view are not aware of each other. A qucik look on wikipedia show that this type of modeling and controlling is know has MVA. The A is for adapter and also known as mediating controller, so now we are back to the answer here. Should we be using MVA or MVC? How would one achieve true MVC in Laravel? Answer is to use {{Form:model}} facade for true MVC. But then what happens if the view changes? should we be calling model from the view to get the new data? Answer is no, if the view has to change then user should have caused a controller to react kicking off a new cycle of MVC. So what we can see here a mix of MVC and MVA using the Laravel framework, can achieve a highly customized flow based on the needs of the site.

Upvotes: 1

Collin James
Collin James

Reputation: 9280

There is another solution that is especially handy for cases like yours. If you have 15 routes that all ultimately include the inc.header view... well you can see where this is going. You'll have data logic repeated in several places. Patrik suggested using the BaseController which is a good solution but I prefer to use a composer.

View::composer('inc.header', function ($view)
{
    $view->some_data = MyModel::where(...)->get();
});

It doesn't get much easier then that. :)

Upvotes: 2

pat
pat

Reputation: 5797

Never do anything more than loop thru your data in your view layer. Basically a normal MVC pattern in laravel could be something like this:

It all begins with the routing layer (which btw. is fantastic in laravel)

Using closures

Route::get('/home', function()
{

 //Here data is an array, normally you would fetch data 
 //from your database here and pass it to the View.

 $data = array('this', 'is', 'my', 'data-array');
 return View::make('my.view')->with(compact('data');

});

Using controllers (and a controller method)

//the same route is bound to a controller method
Route::get('/home','HomeController@myFunction');

The controller for the above could look something like this:

<?php

class HomeController extends BaseController {

  //The function you call from your route
  public function myFunction()
  {

     $data = array('this', 'is', 'my', 'data-array');
     return View::make('my.view')->with(compact('data');

  }

}

The above example just shows the VC in MVC, but generally you pass data from your models in the same way.

Heres a quick one:

Model usage in controllers

  public function myFunction($user)
  {

     $userdata = User::find($user)->orderBy('firstname', 'desc');
     $infodata = Event::find(1)->course;
     return View::make('my.view')->with(compact('data', 'infodata');

  }

So the idea is that laravel lets you do things in multiple ways. If you have a minor app, and are sure that you can manage without controllers you could skip the controller and keep everything in your routing layer.

For most apps however the controllers are needed for controlling the dataflow in the application.

If you are totally new to MVC you should check out some tuts on the subject.

EDIT:

Ahaa! So you wanted to share some piece of data in all your views! Well thats simple. Because all your controllers extend the BaseController you can simply pass in the data in there. Like so:

    class BaseController extends Controller {

      public function __construct()
      { 
        $data = array('alot', 'of', 'data');
        return View::share('data', $data);
      }
   }

Now the data variable is available in all the views.

PS. Filters are meant to filter stuff, like to check if certain things are "ok". This could include to check authed users, or form submissions etc.

Upvotes: 3

FR6
FR6

Reputation: 3167

Is it generally a good idea to interact with database in view layer in MVC frameworks?

No, you don't interact with your database (model) in your view layer. MVC stands for "Model View Controller" to separate logic, application data and business rules of your application.

If I should, how can I connect to database from inc/header.php in right way?

I don't want make multiple connections one here at header.php and one in my pages controllers.

You could create a main layout (containing your header) and use this layout for all the pages of your application:

app/views/
    layouts/main.blade.php
    page1.blade.php

layouts/main.blade.php:

<html>
<head>...</head>
<body>

  <div>Your header that will be included in each of your pages</div>

  <!-- The content of the current page: -->
  @yield('body')

</body>
</html>

page1.blade.php:

@extends('layouts.main')

@section('body')
  <div>The content of your page</div>
@stop

Learn more about the Blade templating engine.

Now where do you fetch your data?

The fastest/easiest way to develop is to use the routes as Controllers and as your application evolves you start refactoring your code and create Controllers.

app/routes.php:

Route::get('page1', function(){

  //Fetch your data the way you prefer: SQL, Fluent or Eloquent (Laravel ORM)
  //$data = DB::select('select * from yourtable');
  $data = YourModel::all();

  //Pass your data to the view
  return View::make('page1')
    ->with('data', $data);
});

The data can be fetch using Fluent class or Eloquent ORM.

I suggest you to learn the basics of Laravel to properly create the base of your application so it will be really easy to maintain in the future.

Upvotes: 1

Related Questions