What is the convention regarding the location of queries in Laravel 4?

1

My question is about the following:

public function getIndex()
{
  $users = \User::all();

  return \View::make('admin.users.index')
    ->with('title', 'Usuários')
    ->with('users', $users);
}

In this case I called the all() method of the right Eloquent?

But let's say that in the future this search will need some parameters. Then it would look like this:

$users = \User::where('group_id', 333)->get();

As this may increase (or not), is it okay to leave this statement in the controller ? Or is it better to create a method in the model? For example:

$users = \User::getUsers(333);

I say this more because of convention.

1 - When should I create a method in the model for a query?

2 - How do I avoid getting to the famous "Fat Model"?

If you need more details let me know

    
asked by anonymous 09.05.2014 / 20:08

2 answers

2

I use repository with dependency injection.

What would it be like:

Create in your project a folder inside the app folder with the name repository . Within the folder repository create a php file that will be a default interface with the name RepositoryInterface with this content.

<?php
    interface RepositoryInterface {
        public function all();
        public function toDropDown();
        public function toJson();
        public function toArray();
        public function toListPaginate();
        public function remove($id = NULL);
        public function get($id = NULL);
        public function create();       
    }

Generally, the% created with% is by some purpose being such a model of its own. Being this a base I create the interface on this so that at the time of the injection I have standard names. Example interface , that is, create another PHP file with this content following the example

<?php
    interface RepositoryCreditoInterface extends RepositoryInterface { }

Implement RepositoryCreditoInterface by creating a new PHP file, named RepositoryCreditoInterface , having the content implemented and encoded.

<?php
    class RepositoryCredito implements RepositoryCreditoInterface {
        protected $nameTable = 'creditos';
        public function __construct() { }
        public function create(){
            return new Credito();
        }
        public function get($id = NULL){
            if ($id){
                return Credito::find((int)$id);
            }
            return NULL;
        }
        public function remove($id = NULL)
        {
            if ($id) {
                $model = $this->get($id);
                if ($model) {
                    $model->delete();
                    return true;
                }
            }
            return false;
        }
        public function toListPaginate()
        {           
            return 
                DB::table($this->nameTable)
                    ->where('descricao','LIKE', '%'.Input::get('filtro', '').'%')
                    ->orderBy('descricao','asc')
                    ->paginate(10);
        }
        public function all(){
            return Credito::orderBy('descricao')->get();
        }
        public function toJson(){           
            return Credito::orderBy('descricao')->get()->toJson();
        }
        public function toArray(){
            return Credito::orderBy('descricao')->get()->toArray();
        }
        public function toDropDown(){
            return Credito::orderBy('descricao')->lists('descricao', 'creditoid');
        }
    }

Note that such RepositoryCredito is RepositoryCredito Model (which refers to the Credito table).

All these files creditos , RepositoryInterface and RepositoryCreditoInterface all within that RepositoryCredito folder.

For these classes to go up to Laravel it goes in the folder app\repository it will look like this:

ClassLoader::addDirectories(array(
    app_path().'/commands',
    app_path().'/controllers',
    app_path().'/models'    
    app_path().'/database/seeds',
));

Add to look like this:

ClassLoader::addDirectories(array(
    app_path().'/commands',
    app_path().'/controllers',
    app_path().'/models',        
    app_path().'/repository', 
    app_path().'/database/seeds'
));

That is, the files from that folder app\start\global.php ( repository ) were added to your Laravel project.

Now in the app_path().'/repository' folder, create a file named app\ in your account:

<?php

/*
  |--------------------------------------------------------------------------
  | App::bind IOC
  |--------------------------------------------------------------------------
  |
 */
App::bind('RepositoryCreditoInterface', 'RepositoryCredito');

Note: All interfaces you can register in this file giving a better organization to your project.

For this file to work, it will also go back to ioc.php on the last line, so add:

require app_path().'/ioc.php';

After these settings, to make such an injection dependency on the controler ( app\start\global.php ) is just to pass as in the constructor ( Controller ) the interface you want to be resolved.

Example:

<?php

class CreditoController extends BaseController {
    /*
     * construct
     */

    public function __construct(RepositoryCreditoInterface $repository) {
        parent::__construct();
        View::share('titleView', 'Crédito');
        $this->repository = $repository;
    }

Using the index:

public function index() {
        $model = $this->repository->toListPaginate();
        View::share('routeUpdate', 'admin.credito.update');
        return View::make('admin.credito.index')
                        ->with('model', $model);
}

Note: In the constructor you can pass several interfaces

    
09.05.2014 / 21:36
1

I advise you to use repositories, make your code much more readable and flexible.

Best ( es) way (s) to use Dependency Injection in Laravel

At first it may seem difficult, but after the adjusted structure it is very easy.

    
09.05.2014 / 20:19