learning laravel

Derek Smalls
Derek Smalls
Eat shit!NewcastlePosts: 2,508 in Web Development
I recently started learning laravel and I'm building a little project to try it out 'real world'.

So, I have a view split with some @includes e.g. main.blade.php which includes sidenav.blade.php, header.php etc..

I have created a "Product" model + controller and DB migration and added a few products in the database.

My understanding was that I would then be able to have a function in the Product model that queries the DB and returns all products which I can then use anywhere on the site e.g. On products page I might want to list all products, or in my current case i want to list all product names in the sidenav.blade.php file.

This is where I am running into trouble. The closest I got was to:
  • @yield('productlist') in sidenav
  • create a new view called 'products/index.blade.php' and in there extend sidenav.blade.php
  • put the foreach product loop in there as @section('productlist')
  • Create a Route::get('product', 'ProductController@index') where I see the complete combined files all working as expected

But when i visit a normal page (which is including sidenav) it doesn't recognise the products variable

Is this just completely the wrong way to do this sort of thing? Or am I actually getting close?

Comments

  • calder12
    calder12
    Senior Member Posts: 13,484 edited February 24
    MVC is where you're running into issues I think.

    Models do database actions, they should not (can not) feed views directly.
    Controllers act as a middle ground between views and models
    Views are well views.

    I haven't written anything in Laravel in forever, but basically you create the function in your model to return your data. Then in whatever view you need that data in you make a call in that view's controller to populate a variable with that data, then pass that data to the view's render function.

    Does that help at all?
  • Derek Smalls
    Derek Smalls
    Eat shit! NewcastlePosts: 2,508
    I think where I am having the problem is that sidenav is a partial of a main view (like a master overall template). So there is no controller for that view.
  • calder12
    calder12
    Senior Member Posts: 13,484
    If it's a partial, pass the data to the controller of the main view that holds the partial.
  • calder12
    calder12
    Senior Member Posts: 13,484
    And yes, that does mean you may be making that call from multiple controllers, but that is the point of creating the model. To give you a simple function call that you can repeat multiple times without writing all the code for the query.

    Technically you can call the database directly from the controller, but you shouldn't.
  • Derek Smalls
    Derek Smalls
    Eat shit! NewcastlePosts: 2,508 edited February 24
    This is where I'm confused. Maybe I am just building this wrong.

    This is what I have:

    views/ layouts.admin.main (this is like a base template)
    views/ admin.products.index (empty at the moment)
    views/ admin.dashboard (extends layouts.admin.main)
    views/ layouts.admin.includes.sidenav (this is @included in layouts.admin.main)

    AdminHomeController.php
    public function index()
        {
            return view('admin.dashboard');
        }
    

    Controller.php (this was there on install I think)
    class Controller extends BaseController
    {
        use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
    }
    
    Route::get('/admin/dashboard', 'AdminHomeController@index');
    

    Product.php (model) - now just an empty class
    ProductController.php (model) - now just an empty class

    Currently I can load admin/dashboard and get my base template with the sidenav included.

    The best I managed was this in Product.php I think and a @foreach($products as $product) in admin.products.index file but now I can't remember how I got that working :neutral:
    class Product extends Model
    {
        	$products = \App\Product::all();
    		return view('admin.products.index', compact('products'));
    }
    
  • Derek Smalls
    Derek Smalls
    Eat shit! NewcastlePosts: 2,508
    and btw...what made you give up on laravel?
  • calder12
    calder12
    Senior Member Posts: 13,484 edited February 24
    First, I didn't give up on it, just haven't used it for anything in a while. I still think it's a fantastic framework!

    Okay going by memory, first you don't need a separate controller for each view. Usually I'll go with two, maybe three. One for regular pages, one for user pages and possibly one for admin pages.

    So in your routes file you'll have an entry like this:
    Route::get('/', 'pagesController@index');
    

    Then inside the pagesController index is a function, as are all the other basic pages.
    public function index() {
      $productNames = App\Product::returnProductsByName();
      return View::make('main')->with('products', $productNames );
    }
    

    Your model would also have a function.
    public function returnProductsByName() {
      $products = \App\Product::all();
      return $products;
    }
    

    The resulting views could access the products in a for loop.
    foreach( $products as $product ) {
      echo $product->name;
    }
    

    That's off the top of my head, so the code might not work right out of the box (and I haven't written anything at all in L5 so maybe it even changed since then.

    http://laracasts.com << Trust me, worth every penny, Jeffery Way is awesome.
  • calder12
    calder12
    Senior Member Posts: 13,484
    PS, all those functions go inside the main class.
    Models should never return anything but data.
  • Derek Smalls
    Derek Smalls
    Eat shit! NewcastlePosts: 2,508
    Thanks again calder. This is what I had done but couldn't get past an error for hours then realised it was because I needed to make the method in the model 'static'. I still need to read up a bit on when and when not to use static but this should do for now.

    Glad you haven't quit laravel...I got a bit worried I was learning something that people are starting to ditch.

    Yeah, I've been learning from Jeffrey's free casts so far...he types lightning fast but knows his stuff.
  • calder12
    calder12
    Senior Member Posts: 13,484
    ha, no like I said Laravel is without question the best PHP framework out there. A colleague and I were almost ready to start a big commercial project with it and just the other days decided to switch gears to Elixir with Phoenix and React, but we were both very pleased with Laravel and what it offered!
  • Derek Smalls
    Derek Smalls
    Eat shit! NewcastlePosts: 2,508
    ah no...I've been working on this and it all seemed to be going well until I realised that this means I have to repeat something for every single view. I was trying to do as you said; just using a single controller so this is happening:
    public function index() {
      $productNames = App\Product::returnProductsByName();
      return view('admin.dashboard', compact('productNames') );
    }
    
    public function settings() {
      $productNames = App\Product::returnProductsByName();
      return view('admin.settings', compact('productNames') );
    }
    

    It works but I really doubt I should be repeating this for every view/page I create?
  • calder12
    calder12
    Senior Member Posts: 13,484
    Which is 100% fine. DRY is meant to not write huge functions out multiple times, which is why you have a Model. Some of your model functions will be far more complicated, returning subsets of data but your controller calls will still just be one line.

    In the case of data that you are literally going to use everywhere look into setting up a global variable, I am not sure how that works in Laravel, then you only have to reference the global in the view return.
  • Derek Smalls
    Derek Smalls
    Eat shit! NewcastlePosts: 2,508
    what is your view on the way Jeffrey appears to suggest that every model should have a controller and the methods should all be named index, show, create, delete etc...? Doing it the way I'm now doing it would mean I would have to have settingsCreate, settingsShow, productsShow etc...
  • calder12
    calder12
    Senior Member Posts: 13,484
    When choosing between my advice and Jeffery's. Choose Jeffery's.

    I haven't seen his patterns or know the reasoning behind them, but he's better than I am.
  • Derek Smalls
    Derek Smalls
    Eat shit! NewcastlePosts: 2,508
    there's a good chance you are both right and it's just me reading into it wrong
  • calder12
    calder12
    Senior Member Posts: 13,484
    The separate controller pattern is pretty standard CRUD, (I didn't read your last comment right).

    In smaller applications I prefer less controllers, but in larger more complicated ones the multiple controllers pattern handling a single model can work well too. I just like knowing if I am working on a specific section of my site, all my methods are in one place.
Sign In or Register to comment.
© Copyright 2003 - 2016 - DT by Kooc Media